From ead6c569132b5c1005c40ebed357f8fb9a1028ba Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 23 Dec 2025 22:47:41 -0800 Subject: [PATCH 01/20] tests: add separated github workflows for testing --- .github/workflows/{java.yml => java-glue.yml} | 35 +++-- .github/workflows/java-hive2.yml | 62 +++++++++ .github/workflows/java-hive3.yml | 62 +++++++++ .github/workflows/java-iceberg.yml | 62 +++++++++ ...gration-hive2.yml => java-integ-hive2.yml} | 83 ++++++------ ...gration-hive3.yml => java-integ-hive3.yml} | 83 ++++++------ ...ion-polaris.yml => java-integ-polaris.yml} | 76 +++++------ ...gration-unity.yml => java-integ-unity.yml} | 75 +++++------ .github/workflows/java-polaris.yml | 62 +++++++++ .github/workflows/java-unity.yml | 56 +++----- .../workflows/{python.yml => python-glue.yml} | 32 +++-- .github/workflows/python-hive.yml | 64 +++++++++ .github/workflows/python-iceberg.yml | 64 +++++++++ .github/workflows/python-integ-hive.yml | 97 +++++++++++++ .github/workflows/python-integ-polaris.yml | 112 +++++++++++++++ .github/workflows/python-integ-unity.yml | 96 +++++++++++++ .github/workflows/python-unity.yml | 64 +++++++++ Makefile | 85 ++++++++---- java/Makefile | 127 ++++++++++++++++-- python/Makefile | 103 ++++++++++++-- 20 files changed, 1212 insertions(+), 288 deletions(-) rename .github/workflows/{java.yml => java-glue.yml} (67%) create mode 100644 .github/workflows/java-hive2.yml create mode 100644 .github/workflows/java-hive3.yml create mode 100644 .github/workflows/java-iceberg.yml rename .github/workflows/{integration-hive2.yml => java-integ-hive2.yml} (57%) rename .github/workflows/{integration-hive3.yml => java-integ-hive3.yml} (57%) rename .github/workflows/{integration-polaris.yml => java-integ-polaris.yml} (67%) rename .github/workflows/{integration-unity.yml => java-integ-unity.yml} (60%) create mode 100644 .github/workflows/java-polaris.yml rename .github/workflows/{python.yml => python-glue.yml} (67%) create mode 100644 .github/workflows/python-hive.yml create mode 100644 .github/workflows/python-iceberg.yml create mode 100644 .github/workflows/python-integ-hive.yml create mode 100644 .github/workflows/python-integ-polaris.yml create mode 100644 .github/workflows/python-integ-unity.yml create mode 100644 .github/workflows/python-unity.yml diff --git a/.github/workflows/java.yml b/.github/workflows/java-glue.yml similarity index 67% rename from .github/workflows/java.yml rename to .github/workflows/java-glue.yml index b157435..89ef3ea 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java-glue.yml @@ -10,12 +10,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Java +name: Java Glue on: push: branches: - main + paths: + - java/lance-namespace-glue/** + - java/pom.xml + - .github/workflows/java-glue.yml pull_request: types: - opened @@ -23,20 +27,21 @@ on: - ready_for_review - reopened paths: - - java/** - - .github/workflows/java.yml + - java/lance-namespace-glue/** + - java/pom.xml + - .github/workflows/java-glue.yml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - linux-build: + test: runs-on: ubuntu-24.04 - timeout-minutes: 60 + timeout-minutes: 30 strategy: matrix: - java-version: [ 11, 17 ] + java-version: [11, 17] steps: - name: Checkout repo uses: actions/checkout@v4 @@ -46,18 +51,12 @@ jobs: distribution: temurin java-version: ${{ matrix.java-version }} cache: "maven" - - name: Check code style - working-directory: java - run: ./mvnw spotless:check - - name: Build with Java ${{ matrix.java-version }} + - name: Lint working-directory: java - run: ./mvnw install -DskipTests - - name: Run unit tests + run: make lint-glue + - name: Build working-directory: java - run: | - ./mvnw test -pl lance-namespace-glue - ./mvnw test -pl lance-namespace-polaris - - name: Build all modules with make (Java 17 only) - if: matrix.java-version == 17 + run: make build-glue + - name: Test working-directory: java - run: make build + run: make test-glue diff --git a/.github/workflows/java-hive2.yml b/.github/workflows/java-hive2.yml new file mode 100644 index 0000000..3b32107 --- /dev/null +++ b/.github/workflows/java-hive2.yml @@ -0,0 +1,62 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Hive2 + +on: + push: + branches: + - main + paths: + - java/lance-namespace-hive2/** + - java/pom.xml + - .github/workflows/java-hive2.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-hive2/** + - java/pom.xml + - .github/workflows/java-hive2.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + java-version: [11, 17] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java-version }} + cache: "maven" + - name: Lint + working-directory: java + run: make lint-hive2 + - name: Build + working-directory: java + run: make build-hive2 + - name: Test + working-directory: java + run: make test-hive2 diff --git a/.github/workflows/java-hive3.yml b/.github/workflows/java-hive3.yml new file mode 100644 index 0000000..cf8d9c3 --- /dev/null +++ b/.github/workflows/java-hive3.yml @@ -0,0 +1,62 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Hive3 + +on: + push: + branches: + - main + paths: + - java/lance-namespace-hive3/** + - java/pom.xml + - .github/workflows/java-hive3.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-hive3/** + - java/pom.xml + - .github/workflows/java-hive3.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + java-version: [11, 17] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java-version }} + cache: "maven" + - name: Lint + working-directory: java + run: make lint-hive3 + - name: Build + working-directory: java + run: make build-hive3 + - name: Test + working-directory: java + run: make test-hive3 diff --git a/.github/workflows/java-iceberg.yml b/.github/workflows/java-iceberg.yml new file mode 100644 index 0000000..b121174 --- /dev/null +++ b/.github/workflows/java-iceberg.yml @@ -0,0 +1,62 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Iceberg + +on: + push: + branches: + - main + paths: + - java/lance-namespace-iceberg/** + - java/pom.xml + - .github/workflows/java-iceberg.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-iceberg/** + - java/pom.xml + - .github/workflows/java-iceberg.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + java-version: [11, 17] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java-version }} + cache: "maven" + - name: Lint + working-directory: java + run: make lint-iceberg + - name: Build + working-directory: java + run: make build-iceberg + - name: Test + working-directory: java + run: make test-iceberg diff --git a/.github/workflows/integration-hive2.yml b/.github/workflows/java-integ-hive2.yml similarity index 57% rename from .github/workflows/integration-hive2.yml rename to .github/workflows/java-integ-hive2.yml index 82bf0d4..d288006 100644 --- a/.github/workflows/integration-hive2.yml +++ b/.github/workflows/java-integ-hive2.yml @@ -1,20 +1,35 @@ -name: Hive2 Integration Tests +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Hive2 Integration on: push: - branches: [main] + branches: + - main paths: - - 'java/lance-namespace-hive2/**' - - 'docker/hive2/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-hive2.yml' + - java/lance-namespace-hive2/** + - docker/hive2/** + - .github/workflows/java-integ-hive2.yml pull_request: - branches: [main] + types: + - opened + - synchronize + - ready_for_review + - reopened paths: - - 'java/lance-namespace-hive2/**' - - 'docker/hive2/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-hive2.yml' + - java/lance-namespace-hive2/** + - docker/hive2/** + - .github/workflows/java-integ-hive2.yml workflow_dispatch: concurrency: @@ -23,31 +38,21 @@ concurrency: jobs: integration-test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 30 - steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - + java-version: "17" + distribution: "temurin" + cache: "maven" - name: Download PostgreSQL JDBC driver - run: | - mkdir -p docker/hive2 - curl -sSL -o docker/hive2/postgresql-42.7.3.jar \ - https://jdbc.postgresql.org/download/postgresql-42.7.3.jar - + run: make docker-setup - name: Start Hive2 Metastore - run: | - docker compose -f docker/hive2/docker-compose.yml up -d - echo "Waiting for services to start..." - + run: make docker-up-hive2 - name: Wait for Hive2 Metastore to be ready run: | echo "Waiting for Hive2 Metastore to be ready..." @@ -62,27 +67,17 @@ jobs: docker compose -f docker/hive2/docker-compose.yml logs exit 1 } - echo "Hive2 Metastore is ready" - - - name: Verify Hive2 connectivity - run: | - # Wait a bit more for thrift to be fully ready sleep 10 nc -z localhost 9083 || { echo "Cannot connect to Hive2 Metastore on port 9083" docker compose -f docker/hive2/docker-compose.yml logs exit 1 } - echo "Hive2 Metastore is accepting connections on port 9083" - - - name: Run Hive2 integration tests - working-directory: java - run: | - ./mvnw test -pl lance-namespace-hive2 \ - -Dtest="*IntegrationTest" \ - -DfailIfNoTests=false \ - -Dmaven.test.failure.ignore=false - + echo "Hive2 Metastore is ready" + - name: Build + run: make build-java + - name: Run integration tests + run: make java-integ-test-hive2 - name: Collect logs on failure if: failure() run: | @@ -94,8 +89,6 @@ jobs: echo "" echo "=== PostgreSQL Logs ===" docker compose -f docker/hive2/docker-compose.yml logs postgres-hive2 - - name: Cleanup if: always() - run: | - docker compose -f docker/hive2/docker-compose.yml down -v + run: make docker-down-hive2 diff --git a/.github/workflows/integration-hive3.yml b/.github/workflows/java-integ-hive3.yml similarity index 57% rename from .github/workflows/integration-hive3.yml rename to .github/workflows/java-integ-hive3.yml index b2bdcdd..5d893ff 100644 --- a/.github/workflows/integration-hive3.yml +++ b/.github/workflows/java-integ-hive3.yml @@ -1,20 +1,35 @@ -name: Hive3 Integration Tests +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Hive3 Integration on: push: - branches: [main] + branches: + - main paths: - - 'java/lance-namespace-hive3/**' - - 'docker/hive3/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-hive3.yml' + - java/lance-namespace-hive3/** + - docker/hive3/** + - .github/workflows/java-integ-hive3.yml pull_request: - branches: [main] + types: + - opened + - synchronize + - ready_for_review + - reopened paths: - - 'java/lance-namespace-hive3/**' - - 'docker/hive3/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-hive3.yml' + - java/lance-namespace-hive3/** + - docker/hive3/** + - .github/workflows/java-integ-hive3.yml workflow_dispatch: concurrency: @@ -23,31 +38,21 @@ concurrency: jobs: integration-test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 30 - steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - + java-version: "17" + distribution: "temurin" + cache: "maven" - name: Download PostgreSQL JDBC driver - run: | - mkdir -p docker/hive3 - curl -sSL -o docker/hive3/postgresql-42.7.3.jar \ - https://jdbc.postgresql.org/download/postgresql-42.7.3.jar - + run: make docker-setup - name: Start Hive3 Metastore - run: | - docker compose -f docker/hive3/docker-compose.yml up -d - echo "Waiting for services to start..." - + run: make docker-up-hive3 - name: Wait for Hive3 Metastore to be ready run: | echo "Waiting for Hive3 Metastore to be ready..." @@ -62,27 +67,17 @@ jobs: docker compose -f docker/hive3/docker-compose.yml logs exit 1 } - echo "Hive3 Metastore is ready" - - - name: Verify Hive3 connectivity - run: | - # Wait a bit more for thrift to be fully ready sleep 10 nc -z localhost 9084 || { echo "Cannot connect to Hive3 Metastore on port 9084" docker compose -f docker/hive3/docker-compose.yml logs exit 1 } - echo "Hive3 Metastore is accepting connections on port 9084" - - - name: Run Hive3 integration tests - working-directory: java - run: | - ./mvnw test -pl lance-namespace-hive3 \ - -Dtest="*IntegrationTest" \ - -DfailIfNoTests=false \ - -Dmaven.test.failure.ignore=false - + echo "Hive3 Metastore is ready" + - name: Build + run: make build-java + - name: Run integration tests + run: make java-integ-test-hive3 - name: Collect logs on failure if: failure() run: | @@ -94,8 +89,6 @@ jobs: echo "" echo "=== PostgreSQL Logs ===" docker compose -f docker/hive3/docker-compose.yml logs postgres-hive3 - - name: Cleanup if: always() - run: | - docker compose -f docker/hive3/docker-compose.yml down -v + run: make docker-down-hive3 diff --git a/.github/workflows/integration-polaris.yml b/.github/workflows/java-integ-polaris.yml similarity index 67% rename from .github/workflows/integration-polaris.yml rename to .github/workflows/java-integ-polaris.yml index e812a76..f36906b 100644 --- a/.github/workflows/integration-polaris.yml +++ b/.github/workflows/java-integ-polaris.yml @@ -1,20 +1,35 @@ -name: Polaris Integration Tests +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Polaris Integration on: push: - branches: [main] + branches: + - main paths: - - 'java/lance-namespace-polaris/**' - - 'docker/polaris/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-polaris.yml' + - java/lance-namespace-polaris/** + - docker/polaris/** + - .github/workflows/java-integ-polaris.yml pull_request: - branches: [main] + types: + - opened + - synchronize + - ready_for_review + - reopened paths: - - 'java/lance-namespace-polaris/**' - - 'docker/polaris/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-polaris.yml' + - java/lance-namespace-polaris/** + - docker/polaris/** + - .github/workflows/java-integ-polaris.yml workflow_dispatch: concurrency: @@ -23,25 +38,19 @@ concurrency: jobs: integration-test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 30 - steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - + java-version: "17" + distribution: "temurin" + cache: "maven" - name: Start Polaris - run: | - docker compose -f docker/polaris/docker-compose.yml up -d - echo "Waiting for services to start..." - + run: make docker-up-polaris - name: Wait for Polaris to be ready run: | echo "Waiting for Polaris to be ready..." @@ -56,21 +65,16 @@ jobs: exit 1 } echo "Polaris is ready" - - name: Create test catalog run: | - # Get OAuth token TOKEN=$(curl -s -X POST http://localhost:8181/api/catalog/v1/oauth/tokens \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=client_credentials&client_id=root&client_secret=s3cr3t&scope=PRINCIPAL_ROLE:ALL' | \ python3 -c "import sys, json; print(json.load(sys.stdin).get('access_token', ''))") - if [ -z "$TOKEN" ]; then echo "Failed to get OAuth token" exit 1 fi - - # Create test catalog curl -s -X POST http://localhost:8181/api/catalog/v1/catalogs \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ @@ -84,17 +88,11 @@ jobs: "storageType": "FILE" } }' || echo "Catalog may already exist" - echo "Test catalog created/verified" - - - name: Run Polaris integration tests - working-directory: java - run: | - ./mvnw test -pl lance-namespace-polaris \ - -Dtest="*IntegrationTest" \ - -DfailIfNoTests=false \ - -Dmaven.test.failure.ignore=false - + - name: Build + run: make build-java + - name: Run integration tests + run: make java-integ-test-polaris - name: Collect logs on failure if: failure() run: | @@ -106,8 +104,6 @@ jobs: echo "" echo "=== PostgreSQL Logs ===" docker compose -f docker/polaris/docker-compose.yml logs postgres-polaris - - name: Cleanup if: always() - run: | - docker compose -f docker/polaris/docker-compose.yml down -v + run: make docker-down-polaris diff --git a/.github/workflows/integration-unity.yml b/.github/workflows/java-integ-unity.yml similarity index 60% rename from .github/workflows/integration-unity.yml rename to .github/workflows/java-integ-unity.yml index 1c89570..ed4d054 100644 --- a/.github/workflows/integration-unity.yml +++ b/.github/workflows/java-integ-unity.yml @@ -1,20 +1,35 @@ -name: Unity Catalog Integration Tests +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Unity Integration on: push: - branches: [main] + branches: + - main paths: - - 'java/lance-namespace-unity/**' - - 'docker/unity/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-unity.yml' + - java/lance-namespace-unity/** + - docker/unity/** + - .github/workflows/java-integ-unity.yml pull_request: - branches: [main] + types: + - opened + - synchronize + - ready_for_review + - reopened paths: - - 'java/lance-namespace-unity/**' - - 'docker/unity/**' - - 'docker/docker-compose.yml' - - '.github/workflows/integration-unity.yml' + - java/lance-namespace-unity/** + - docker/unity/** + - .github/workflows/java-integ-unity.yml workflow_dispatch: concurrency: @@ -23,25 +38,19 @@ concurrency: jobs: integration-test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 30 - steps: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 17 uses: actions/setup-java@v4 with: - java-version: '17' - distribution: 'temurin' - cache: 'maven' - + java-version: "17" + distribution: "temurin" + cache: "maven" - name: Start Unity Catalog - run: | - docker compose -f docker/unity/docker-compose.yml up -d - echo "Waiting for services to start..." - + run: make docker-up-unity - name: Wait for Unity Catalog to be ready run: | echo "Waiting for Unity Catalog to be ready..." @@ -56,31 +65,21 @@ jobs: exit 1 } echo "Unity Catalog is ready" - - name: Create test catalog run: | - # Create test catalog curl -s -X POST http://localhost:8080/api/2.1/unity-catalog/catalogs \ -H 'Content-Type: application/json' \ -d '{"name": "lance_test", "comment": "Test catalog for Lance integration tests"}' \ || echo "Catalog may already exist" - - # Verify catalog exists curl -sf http://localhost:8080/api/2.1/unity-catalog/catalogs/lance_test || { echo "Failed to create/verify test catalog" exit 1 } - echo "Test catalog created/verified" - - - name: Run Unity Catalog integration tests - working-directory: java - run: | - ./mvnw test -pl lance-namespace-unity \ - -Dtest="*IntegrationTest" \ - -DfailIfNoTests=false \ - -Dmaven.test.failure.ignore=false - + - name: Build + run: make build-java + - name: Run integration tests + run: make java-integ-test-unity - name: Collect logs on failure if: failure() run: | @@ -89,8 +88,6 @@ jobs: echo "" echo "=== Unity Catalog Logs ===" docker compose -f docker/unity/docker-compose.yml logs unity-catalog - - name: Cleanup if: always() - run: | - docker compose -f docker/unity/docker-compose.yml down -v + run: make docker-down-unity diff --git a/.github/workflows/java-polaris.yml b/.github/workflows/java-polaris.yml new file mode 100644 index 0000000..51e45d9 --- /dev/null +++ b/.github/workflows/java-polaris.yml @@ -0,0 +1,62 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Polaris + +on: + push: + branches: + - main + paths: + - java/lance-namespace-polaris/** + - java/pom.xml + - .github/workflows/java-polaris.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-polaris/** + - java/pom.xml + - .github/workflows/java-polaris.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + java-version: [11, 17] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java-version }} + cache: "maven" + - name: Lint + working-directory: java + run: make lint-polaris + - name: Build + working-directory: java + run: make build-polaris + - name: Test + working-directory: java + run: make test-polaris diff --git a/.github/workflows/java-unity.yml b/.github/workflows/java-unity.yml index f0e1e49..964e465 100644 --- a/.github/workflows/java-unity.yml +++ b/.github/workflows/java-unity.yml @@ -10,12 +10,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Java Unity Catalog Tests +name: Java Unity on: push: branches: - main + paths: + - java/lance-namespace-unity/** + - java/pom.xml + - .github/workflows/java-unity.yml pull_request: types: - opened @@ -24,6 +28,7 @@ on: - reopened paths: - java/lance-namespace-unity/** + - java/pom.xml - .github/workflows/java-unity.yml concurrency: @@ -31,12 +36,12 @@ concurrency: cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - unity-catalog-tests: + test: runs-on: ubuntu-24.04 timeout-minutes: 30 strategy: matrix: - java-version: [ 17 ] + java-version: [11, 17] steps: - name: Checkout repo uses: actions/checkout@v4 @@ -46,41 +51,12 @@ jobs: distribution: temurin java-version: ${{ matrix.java-version }} cache: "maven" - - # Start Unity Catalog server using Docker Compose - - name: Start Unity Catalog server - run: | - git clone https://github.com/unitycatalog/unitycatalog.git /tmp/unitycatalog - cd /tmp/unitycatalog - docker compose up -d - # Wait for Unity Catalog to be ready - echo "Waiting for Unity Catalog server to start..." - for i in {1..30}; do - if curl -s http://localhost:8080/api/2.1/unity-catalog/catalogs > /dev/null; then - echo "Unity Catalog server is ready" - break - fi - echo "Waiting for Unity Catalog server... ($i/30)" - sleep 2 - done - # Verify server is responding - curl -s http://localhost:8080/api/2.1/unity-catalog/catalogs || exit 1 - - # Run Unity namespace tests - - name: Run Unity Catalog tests with Java ${{ matrix.java-version }} + - name: Lint working-directory: java - run: ./mvnw test -pl lance-namespace-unity -am - - # Clean up Docker containers - - name: Stop Unity Catalog server - if: always() - run: | - cd /tmp/unitycatalog - docker compose down - - # Show Docker logs if tests failed - - name: Show Unity Catalog logs on failure - if: failure() - run: | - cd /tmp/unitycatalog - docker compose logs + run: make lint-unity + - name: Build + working-directory: java + run: make build-unity + - name: Test + working-directory: java + run: make test-unity diff --git a/.github/workflows/python.yml b/.github/workflows/python-glue.yml similarity index 67% rename from .github/workflows/python.yml rename to .github/workflows/python-glue.yml index dc67340..464ed66 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python-glue.yml @@ -10,12 +10,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Python +name: Python Glue on: push: branches: - main + paths: + - python/src/lance_namespace_impls/glue.py + - python/tests/test_glue.py + - python/pyproject.toml + - .github/workflows/python-glue.yml pull_request: types: - opened @@ -23,20 +28,22 @@ on: - ready_for_review - reopened paths: - - python/** - - .github/workflows/python.yml + - python/src/lance_namespace_impls/glue.py + - python/tests/test_glue.py + - python/pyproject.toml + - .github/workflows/python-glue.yml concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: - linux-build: + test: runs-on: ubuntu-24.04 timeout-minutes: 30 strategy: matrix: - python-version: [ "3.10", "3.11", "3.12" ] + python-version: ["3.10", "3.11", "3.12"] steps: - name: Checkout repo uses: actions/checkout@v4 @@ -46,13 +53,12 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v4 - - name: Install dependencies and run tests + - name: Install dependencies + working-directory: python + run: make install-glue + - name: Lint working-directory: python - run: | - uv sync - uv run pytest - - name: Check code style + run: make lint-glue + - name: Test working-directory: python - run: | - uv run ruff check . - uv run ruff format --check . + run: make test-glue diff --git a/.github/workflows/python-hive.yml b/.github/workflows/python-hive.yml new file mode 100644 index 0000000..abb027f --- /dev/null +++ b/.github/workflows/python-hive.yml @@ -0,0 +1,64 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Hive + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/hive.py + - python/tests/test_hive.py + - python/pyproject.toml + - .github/workflows/python-hive.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/hive.py + - python/tests/test_hive.py + - python/pyproject.toml + - .github/workflows/python-hive.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Install dependencies + working-directory: python + run: make install-hive + - name: Lint + working-directory: python + run: make lint-hive + - name: Test + working-directory: python + run: make test-hive diff --git a/.github/workflows/python-iceberg.yml b/.github/workflows/python-iceberg.yml new file mode 100644 index 0000000..e43ee9d --- /dev/null +++ b/.github/workflows/python-iceberg.yml @@ -0,0 +1,64 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Iceberg + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/tests/test_iceberg.py + - python/pyproject.toml + - .github/workflows/python-iceberg.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/tests/test_iceberg.py + - python/pyproject.toml + - .github/workflows/python-iceberg.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Install dependencies + working-directory: python + run: make install-iceberg + - name: Lint + working-directory: python + run: make lint-iceberg + - name: Test + working-directory: python + run: make test-iceberg diff --git a/.github/workflows/python-integ-hive.yml b/.github/workflows/python-integ-hive.yml new file mode 100644 index 0000000..3d118a9 --- /dev/null +++ b/.github/workflows/python-integ-hive.yml @@ -0,0 +1,97 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Hive Integration + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/hive.py + - python/tests/test_hive.py + - docker/hive2/** + - .github/workflows/python-integ-hive.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/hive.py + - python/tests/test_hive.py + - docker/hive2/** + - .github/workflows/python-integ-hive.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Download PostgreSQL JDBC driver + run: make docker-setup + - name: Start Hive2 Metastore + run: make docker-up-hive2 + - name: Wait for Hive2 Metastore to be ready + run: | + echo "Waiting for Hive2 Metastore to be ready..." + timeout 180 bash -c ' + until docker compose -f docker/hive2/docker-compose.yml ps | grep -q "healthy"; do + echo "Waiting for healthy status..." + docker compose -f docker/hive2/docker-compose.yml ps + sleep 10 + done + ' || { + echo "Timeout waiting for Hive2 Metastore" + docker compose -f docker/hive2/docker-compose.yml logs + exit 1 + } + sleep 10 + nc -z localhost 9083 || { + echo "Cannot connect to Hive2 Metastore on port 9083" + docker compose -f docker/hive2/docker-compose.yml logs + exit 1 + } + echo "Hive2 Metastore is ready" + - name: Install dependencies + working-directory: python + run: make install-hive + - name: Run integration tests + run: make python-integ-test-hive + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose Status ===" + docker compose -f docker/hive2/docker-compose.yml ps + echo "" + echo "=== Hive2 Metastore Logs ===" + docker compose -f docker/hive2/docker-compose.yml logs hive2-metastore + echo "" + echo "=== PostgreSQL Logs ===" + docker compose -f docker/hive2/docker-compose.yml logs postgres-hive2 + - name: Cleanup + if: always() + run: make docker-down-hive2 diff --git a/.github/workflows/python-integ-polaris.yml b/.github/workflows/python-integ-polaris.yml new file mode 100644 index 0000000..6292387 --- /dev/null +++ b/.github/workflows/python-integ-polaris.yml @@ -0,0 +1,112 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Polaris Integration + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/tests/test_polaris.py + - docker/polaris/** + - .github/workflows/python-integ-polaris.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/tests/test_polaris.py + - docker/polaris/** + - .github/workflows/python-integ-polaris.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Start Polaris + run: make docker-up-polaris + - name: Wait for Polaris to be ready + run: | + echo "Waiting for Polaris to be ready..." + timeout 180 bash -c ' + until curl -sf http://localhost:8182/q/health > /dev/null 2>&1; do + echo "Waiting for Polaris health endpoint..." + sleep 5 + done + ' || { + echo "Timeout waiting for Polaris" + docker compose -f docker/polaris/docker-compose.yml logs + exit 1 + } + echo "Polaris is ready" + - name: Create test catalog + run: | + TOKEN=$(curl -s -X POST http://localhost:8181/api/catalog/v1/oauth/tokens \ + -H 'Content-Type: application/x-www-form-urlencoded' \ + -d 'grant_type=client_credentials&client_id=root&client_secret=s3cr3t&scope=PRINCIPAL_ROLE:ALL' | \ + python3 -c "import sys, json; print(json.load(sys.stdin).get('access_token', ''))") + if [ -z "$TOKEN" ]; then + echo "Failed to get OAuth token" + exit 1 + fi + curl -s -X POST http://localhost:8181/api/catalog/v1/catalogs \ + -H "Authorization: Bearer $TOKEN" \ + -H 'Content-Type: application/json' \ + -d '{ + "name": "test_catalog", + "type": "INTERNAL", + "properties": { + "default-base-location": "file:///data/warehouse/test_catalog" + }, + "storageConfigInfo": { + "storageType": "FILE" + } + }' || echo "Catalog may already exist" + echo "Test catalog created/verified" + - name: Install dependencies + working-directory: python + run: make install-iceberg + - name: Run integration tests + run: make python-integ-test-polaris + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose Status ===" + docker compose -f docker/polaris/docker-compose.yml ps + echo "" + echo "=== Polaris Logs ===" + docker compose -f docker/polaris/docker-compose.yml logs polaris + echo "" + echo "=== PostgreSQL Logs ===" + docker compose -f docker/polaris/docker-compose.yml logs postgres-polaris + - name: Cleanup + if: always() + run: make docker-down-polaris diff --git a/.github/workflows/python-integ-unity.yml b/.github/workflows/python-integ-unity.yml new file mode 100644 index 0000000..36b7b0b --- /dev/null +++ b/.github/workflows/python-integ-unity.yml @@ -0,0 +1,96 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Unity Integration + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/unity.py + - python/tests/test_unity.py + - docker/unity/** + - .github/workflows/python-integ-unity.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/unity.py + - python/tests/test_unity.py + - docker/unity/** + - .github/workflows/python-integ-unity.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Start Unity Catalog + run: make docker-up-unity + - name: Wait for Unity Catalog to be ready + run: | + echo "Waiting for Unity Catalog to be ready..." + timeout 120 bash -c ' + until curl -sf http://localhost:8080/api/2.1/unity-catalog/catalogs > /dev/null 2>&1; do + echo "Waiting for Unity Catalog API..." + sleep 5 + done + ' || { + echo "Timeout waiting for Unity Catalog" + docker compose -f docker/unity/docker-compose.yml logs + exit 1 + } + echo "Unity Catalog is ready" + - name: Create test catalog + run: | + curl -s -X POST http://localhost:8080/api/2.1/unity-catalog/catalogs \ + -H 'Content-Type: application/json' \ + -d '{"name": "lance_test", "comment": "Test catalog for Lance integration tests"}' \ + || echo "Catalog may already exist" + curl -sf http://localhost:8080/api/2.1/unity-catalog/catalogs/lance_test || { + echo "Failed to create/verify test catalog" + exit 1 + } + echo "Test catalog created/verified" + - name: Install dependencies + working-directory: python + run: make install-unity + - name: Run integration tests + run: make python-integ-test-unity + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose Status ===" + docker compose -f docker/unity/docker-compose.yml ps + echo "" + echo "=== Unity Catalog Logs ===" + docker compose -f docker/unity/docker-compose.yml logs unity-catalog + - name: Cleanup + if: always() + run: make docker-down-unity diff --git a/.github/workflows/python-unity.yml b/.github/workflows/python-unity.yml new file mode 100644 index 0000000..d57ea21 --- /dev/null +++ b/.github/workflows/python-unity.yml @@ -0,0 +1,64 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Unity + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/unity.py + - python/tests/test_unity.py + - python/pyproject.toml + - .github/workflows/python-unity.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/unity.py + - python/tests/test_unity.py + - python/pyproject.toml + - .github/workflows/python-unity.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Install dependencies + working-directory: python + run: make install-unity + - name: Lint + working-directory: python + run: make lint-unity + - name: Test + working-directory: python + run: make test-unity diff --git a/Makefile b/Makefile index 97a7572..083a2b3 100644 --- a/Makefile +++ b/Makefile @@ -10,37 +10,53 @@ # See the License for the specific language governing permissions and # limitations under the License. +# ============================================================================ +# Python +# ============================================================================ + .PHONY: clean-python clean-python: - cd python; make clean + cd python && make clean .PHONY: build-python build-python: - cd python; make build + cd python && make build .PHONY: test-python test-python: - cd python; make test + cd python && make test + +# ============================================================================ +# Java +# ============================================================================ .PHONY: clean-java clean-java: - cd java; make clean + cd java && make clean .PHONY: build-java build-java: - cd java; make build + cd java && make build .PHONY: test-java test-java: - cd java; make test + cd java && make test + +# ============================================================================ +# Docs +# ============================================================================ .PHONY: build-docs build-docs: - cd docs; make build + cd docs && make build .PHONY: serve-docs serve-docs: - cd docs; make serve + cd docs && make serve + +# ============================================================================ +# All +# ============================================================================ .PHONY: clean clean: clean-python clean-java @@ -105,28 +121,45 @@ docker-down-unity: cd docker && make down-unity # ============================================================================ -# Integration test targets +# Java Integration test targets # ============================================================================ -.PHONY: integration-test-java -integration-test-java: - cd java && ./mvnw test -Dtest="*IntegrationTest" -DfailIfNoTests=false +.PHONY: java-integ-test +java-integ-test: + cd java && make integ-test + +.PHONY: java-integ-test-hive2 +java-integ-test-hive2: + cd java && make integ-test-hive2 + +.PHONY: java-integ-test-hive3 +java-integ-test-hive3: + cd java && make integ-test-hive3 -.PHONY: integration-test-hive2 -integration-test-hive2: - cd java && ./mvnw test -pl lance-namespace-hive2 -Dtest="*IntegrationTest" -DfailIfNoTests=false +.PHONY: java-integ-test-polaris +java-integ-test-polaris: + cd java && make integ-test-polaris + +.PHONY: java-integ-test-unity +java-integ-test-unity: + cd java && make integ-test-unity + +# ============================================================================ +# Python Integration test targets +# ============================================================================ -.PHONY: integration-test-hive3 -integration-test-hive3: - cd java && ./mvnw test -pl lance-namespace-hive3 -Dtest="*IntegrationTest" -DfailIfNoTests=false +.PHONY: python-integ-test +python-integ-test: + cd python && make integ-test -.PHONY: integration-test-polaris -integration-test-polaris: - cd java && ./mvnw test -pl lance-namespace-polaris -Dtest="*IntegrationTest" -DfailIfNoTests=false +.PHONY: python-integ-test-hive +python-integ-test-hive: + cd python && make integ-test-hive -.PHONY: integration-test-unity -integration-test-unity: - cd java && ./mvnw test -pl lance-namespace-unity -Dtest="*IntegrationTest" -DfailIfNoTests=false +.PHONY: python-integ-test-polaris +python-integ-test-polaris: + cd python && make integ-test-polaris -.PHONY: integration-test -integration-test: integration-test-java +.PHONY: python-integ-test-unity +python-integ-test-unity: + cd python && make integ-test-unity diff --git a/java/Makefile b/java/Makefile index 781b067..7c9141a 100644 --- a/java/Makefile +++ b/java/Makefile @@ -10,30 +10,115 @@ # See the License for the specific language governing permissions and # limitations under the License. +# ============================================================================ +# Glue +# ============================================================================ + +.PHONY: lint-glue +lint-glue: + ./mvnw spotless:check -pl lance-namespace-glue + .PHONY: build-glue build-glue: ./mvnw spotless:apply -pl lance-namespace-glue -am - ./mvnw install -pl lance-namespace-glue -am + ./mvnw install -pl lance-namespace-glue -am -DskipTests + +.PHONY: test-glue +test-glue: + ./mvnw test -pl lance-namespace-glue + +# ============================================================================ +# Hive2 +# ============================================================================ + +.PHONY: lint-hive2 +lint-hive2: + ./mvnw spotless:check -pl lance-namespace-hive2 .PHONY: build-hive2 build-hive2: ./mvnw spotless:apply -pl lance-namespace-hive2 -am - ./mvnw install -pl lance-namespace-hive2 -am + ./mvnw install -pl lance-namespace-hive2 -am -DskipTests + +.PHONY: test-hive2 +test-hive2: + ./mvnw test -pl lance-namespace-hive2 -Dtest="!*IntegrationTest" + +# ============================================================================ +# Hive3 +# ============================================================================ + +.PHONY: lint-hive3 +lint-hive3: + ./mvnw spotless:check -pl lance-namespace-hive3 .PHONY: build-hive3 build-hive3: ./mvnw spotless:apply -pl lance-namespace-hive3 -am - ./mvnw install -pl lance-namespace-hive3 -am + ./mvnw install -pl lance-namespace-hive3 -am -DskipTests -.PHONY: build-unity -build-unity: - ./mvnw spotless:apply -pl lance-namespace-unity -am - ./mvnw install -pl lance-namespace-unity -am +.PHONY: test-hive3 +test-hive3: + ./mvnw test -pl lance-namespace-hive3 -Dtest="!*IntegrationTest" + +# ============================================================================ +# Iceberg +# ============================================================================ + +.PHONY: lint-iceberg +lint-iceberg: + ./mvnw spotless:check -pl lance-namespace-iceberg + +.PHONY: build-iceberg +build-iceberg: + ./mvnw spotless:apply -pl lance-namespace-iceberg -am + ./mvnw install -pl lance-namespace-iceberg -am -DskipTests + +.PHONY: test-iceberg +test-iceberg: + ./mvnw test -pl lance-namespace-iceberg + +# ============================================================================ +# Polaris +# ============================================================================ + +.PHONY: lint-polaris +lint-polaris: + ./mvnw spotless:check -pl lance-namespace-polaris .PHONY: build-polaris build-polaris: ./mvnw spotless:apply -pl lance-namespace-polaris -am - ./mvnw install -pl lance-namespace-polaris -am + ./mvnw install -pl lance-namespace-polaris -am -DskipTests + +.PHONY: test-polaris +test-polaris: + ./mvnw test -pl lance-namespace-polaris -Dtest="!*IntegrationTest" + +# ============================================================================ +# Unity +# ============================================================================ + +.PHONY: lint-unity +lint-unity: + ./mvnw spotless:check -pl lance-namespace-unity + +.PHONY: build-unity +build-unity: + ./mvnw spotless:apply -pl lance-namespace-unity -am + ./mvnw install -pl lance-namespace-unity -am -DskipTests + +.PHONY: test-unity +test-unity: + ./mvnw test -pl lance-namespace-unity -Dtest="!*IntegrationTest" + +# ============================================================================ +# All +# ============================================================================ + +.PHONY: lint +lint: + ./mvnw spotless:check .PHONY: clean clean: @@ -42,8 +127,32 @@ clean: .PHONY: build build: ./mvnw spotless:apply - ./mvnw install + ./mvnw install -DskipTests .PHONY: test test: ./mvnw test + +# ============================================================================ +# Integration tests +# ============================================================================ + +.PHONY: integ-test +integ-test: + ./mvnw test -Dtest="*IntegrationTest" -DfailIfNoTests=false + +.PHONY: integ-test-hive2 +integ-test-hive2: + ./mvnw test -pl lance-namespace-hive2 -Dtest="*IntegrationTest" -DfailIfNoTests=false + +.PHONY: integ-test-hive3 +integ-test-hive3: + ./mvnw test -pl lance-namespace-hive3 -Dtest="*IntegrationTest" -DfailIfNoTests=false + +.PHONY: integ-test-polaris +integ-test-polaris: + ./mvnw test -pl lance-namespace-polaris -Dtest="*IntegrationTest" -DfailIfNoTests=false + +.PHONY: integ-test-unity +integ-test-unity: + ./mvnw test -pl lance-namespace-unity -Dtest="*IntegrationTest" -DfailIfNoTests=false diff --git a/python/Makefile b/python/Makefile index 6f06f43..2abf855 100644 --- a/python/Makefile +++ b/python/Makefile @@ -10,34 +10,91 @@ # See the License for the specific language governing permissions and # limitations under the License. -.PHONY: install -install: - uv pip install -e ".[all,dev]" +# ============================================================================ +# Glue +# ============================================================================ + +.PHONY: lint-glue +lint-glue: + uv run ruff check src/lance_namespace_impls/glue.py tests/test_glue.py + uv run ruff format --check src/lance_namespace_impls/glue.py tests/test_glue.py .PHONY: install-glue install-glue: - uv pip install -e ".[glue,dev]" - -.PHONY: install-hive2 -install-hive2: - uv pip install -e ".[hive2,dev]" - -.PHONY: test -test: - uv run pytest tests/ + uv sync --extra glue --extra dev .PHONY: test-glue test-glue: uv run pytest tests/test_glue.py +# ============================================================================ +# Hive +# ============================================================================ + +.PHONY: lint-hive +lint-hive: + uv run ruff check src/lance_namespace_impls/hive.py tests/test_hive.py + uv run ruff format --check src/lance_namespace_impls/hive.py tests/test_hive.py + +.PHONY: install-hive +install-hive: + uv sync --extra hive2 --extra dev + .PHONY: test-hive test-hive: uv run pytest tests/test_hive.py +# ============================================================================ +# Unity +# ============================================================================ + +.PHONY: lint-unity +lint-unity: + uv run ruff check src/lance_namespace_impls/unity.py tests/test_unity.py + uv run ruff format --check src/lance_namespace_impls/unity.py tests/test_unity.py + +.PHONY: install-unity +install-unity: + uv sync --extra unity --extra dev + .PHONY: test-unity test-unity: uv run pytest tests/test_unity.py +# ============================================================================ +# Iceberg +# ============================================================================ + +.PHONY: lint-iceberg +lint-iceberg: + uv run ruff check src/lance_namespace_impls/iceberg.py + uv run ruff format --check src/lance_namespace_impls/iceberg.py + +.PHONY: install-iceberg +install-iceberg: + uv sync --extra dev + +.PHONY: test-iceberg +test-iceberg: + uv run pytest tests/test_iceberg.py + +# ============================================================================ +# All +# ============================================================================ + +.PHONY: lint +lint: + uv run ruff check . + uv run ruff format --check . + +.PHONY: install +install: + uv sync --extra all --extra dev + +.PHONY: test +test: + uv run pytest tests/ + .PHONY: clean clean: rm -rf dist/ @@ -48,9 +105,29 @@ clean: find . -type f -name "*.pyc" -delete .PHONY: build -build: install +build: uv build .PHONY: publish publish: uv build + +# ============================================================================ +# Integration tests +# ============================================================================ + +.PHONY: integ-test +integ-test: + uv run pytest tests/ -m integration + +.PHONY: integ-test-hive +integ-test-hive: + uv run pytest tests/test_hive.py -m integration + +.PHONY: integ-test-polaris +integ-test-polaris: + uv run pytest tests/test_polaris.py -m integration + +.PHONY: integ-test-unity +integ-test-unity: + uv run pytest tests/test_unity.py -m integration From e692eebd5aa70384d9714d1f89b0327513e892c7 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Thu, 25 Dec 2025 21:57:04 -0800 Subject: [PATCH 02/20] fix --- .github/workflows/python-integ-polaris.yml | 6 +- .github/workflows/python-polaris.yml | 64 ++ docs/src/biglake.md | 15 +- docs/src/dataproc.md | 9 +- docs/src/glue.md | 226 ++++- docs/src/hive2.md | 23 +- docs/src/hive3.md | 23 +- docs/src/iceberg.md | 18 +- docs/src/polaris.md | 18 +- docs/src/unity.md | 21 +- java/lance-namespace-glue/pom.xml | 4 + .../lance/namespace/glue/GlueNamespace.java | 295 ++---- .../namespace/glue/GlueNamespaceConfig.java | 23 +- .../glue/GlueToLanceErrorConverter.java | 40 +- .../namespace/glue/TestGlueNamespace.java | 375 +------- java/lance-namespace-hive2/pom.xml | 10 + .../lance/namespace/hive2/ClientPoolImpl.java | 116 +++ .../org/lance/namespace/hive2/CommonUtil.java | 36 + .../namespace/hive2/Hive2ClientPool.java | 2 - .../lance/namespace/hive2/Hive2Namespace.java | 267 ++---- .../namespace/hive2/Hive2NamespaceConfig.java | 27 +- .../org/lance/namespace/hive2/Hive2Util.java | 15 +- .../namespace/hive2/ObjectIdentifier.java | 55 ++ .../org/lance/namespace/hive2/PageUtil.java | 70 ++ .../lance/namespace/hive2/ValidationUtil.java | 35 + .../namespace/hive2/TestHive2Namespace.java | 429 +-------- .../hive2/TestHive2NamespaceIntegration.java | 22 +- java/lance-namespace-hive3/pom.xml | 10 + .../lance/namespace/hive3/ClientPoolImpl.java | 116 +++ .../org/lance/namespace/hive3/CommonUtil.java | 36 + .../org/lance/namespace/hive3/DynMethods.java | 491 ++++++++++ .../namespace/hive3/Hive3ClientPool.java | 3 - .../lance/namespace/hive3/Hive3Namespace.java | 387 ++------ .../namespace/hive3/Hive3NamespaceConfig.java | 27 +- .../org/lance/namespace/hive3/Hive3Util.java | 37 +- .../namespace/hive3/ObjectIdentifier.java | 55 ++ .../org/lance/namespace/hive3/PageUtil.java | 70 ++ .../lance/namespace/hive3/ValidationUtil.java | 35 + .../namespace/hive3/TestHive3Namespace.java | 472 +-------- .../hive3/TestHive3NamespaceIntegration.java | 22 +- java/lance-namespace-iceberg/pom.xml | 8 + .../namespace/iceberg/IcebergModels.java | 2 +- .../namespace/iceberg/IcebergNamespace.java | 258 +++-- java/lance-namespace-impls-core/pom.xml | 97 ++ .../org/lance/namespace/rest/RestClient.java | 412 ++++++++ .../namespace/rest/RestClientException.java | 72 ++ .../org/lance/namespace/test/TestHelper.java | 78 ++ .../namespace/util/ObjectIdentifier.java | 140 +++ .../lance/namespace/util/ValidationUtil.java | 46 + java/lance-namespace-polaris/pom.xml | 8 + .../namespace/polaris/PolarisNamespace.java | 270 ++---- .../polaris/PolarisNamespaceConfig.java | 30 +- .../polaris/TestPolarisNamespace.java | 35 +- .../TestPolarisNamespaceIntegration.java | 45 +- java/lance-namespace-unity/README.md | 8 +- java/lance-namespace-unity/pom.xml | 20 + .../lance/namespace/unity/UnityNamespace.java | 353 ++----- .../namespace/unity/UnityNamespaceConfig.java | 39 +- .../namespace/unity/TestUnityNamespace.java | 102 +- .../unity/TestUnityNamespaceIntegration.java | 23 +- java/pom.xml | 17 +- python/Makefile | 17 + python/README.md | 3 + python/pyproject.toml | 5 + python/src/lance_namespace_impls/__init__.py | 40 +- python/src/lance_namespace_impls/glue.py | 121 +-- .../{hive.py => hive2.py} | 141 +-- python/src/lance_namespace_impls/hive3.py | 763 +++++++++++++++ python/src/lance_namespace_impls/iceberg.py | 479 ++++------ python/src/lance_namespace_impls/polaris.py | 426 +++++++++ .../src/lance_namespace_impls/rest_client.py | 282 ++++++ python/src/lance_namespace_impls/unity.py | 903 +++++++----------- python/tests/test_glue.py | 140 +-- python/tests/{test_hive.py => test_hive2.py} | 158 ++- python/tests/test_hive3.py | 375 ++++++++ python/tests/test_namespace.py | 21 +- python/tests/test_polaris.py | 463 +++++++++ python/tests/test_schema.py | 2 +- python/tests/test_unity.py | 188 ++-- python/uv.lock | 818 ++++++++++++++++ 80 files changed, 7123 insertions(+), 4290 deletions(-) create mode 100644 .github/workflows/python-polaris.yml create mode 100644 java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ClientPoolImpl.java create mode 100644 java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/CommonUtil.java create mode 100644 java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ObjectIdentifier.java create mode 100644 java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/PageUtil.java create mode 100644 java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ValidationUtil.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ClientPoolImpl.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/CommonUtil.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/DynMethods.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ObjectIdentifier.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/PageUtil.java create mode 100644 java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ValidationUtil.java create mode 100644 java/lance-namespace-impls-core/pom.xml create mode 100644 java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClient.java create mode 100644 java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClientException.java create mode 100644 java/lance-namespace-impls-core/src/main/java/org/lance/namespace/test/TestHelper.java create mode 100644 java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ObjectIdentifier.java create mode 100644 java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ValidationUtil.java create mode 100644 python/README.md rename python/src/lance_namespace_impls/{hive.py => hive2.py} (86%) create mode 100644 python/src/lance_namespace_impls/hive3.py create mode 100644 python/src/lance_namespace_impls/polaris.py create mode 100644 python/src/lance_namespace_impls/rest_client.py rename python/tests/{test_hive.py => test_hive2.py} (79%) create mode 100644 python/tests/test_hive3.py create mode 100644 python/tests/test_polaris.py create mode 100644 python/uv.lock diff --git a/.github/workflows/python-integ-polaris.yml b/.github/workflows/python-integ-polaris.yml index 6292387..7766b31 100644 --- a/.github/workflows/python-integ-polaris.yml +++ b/.github/workflows/python-integ-polaris.yml @@ -17,7 +17,7 @@ on: branches: - main paths: - - python/src/lance_namespace_impls/iceberg.py + - python/src/lance_namespace_impls/polaris.py - python/tests/test_polaris.py - docker/polaris/** - .github/workflows/python-integ-polaris.yml @@ -28,7 +28,7 @@ on: - ready_for_review - reopened paths: - - python/src/lance_namespace_impls/iceberg.py + - python/src/lance_namespace_impls/polaris.py - python/tests/test_polaris.py - docker/polaris/** - .github/workflows/python-integ-polaris.yml @@ -93,7 +93,7 @@ jobs: echo "Test catalog created/verified" - name: Install dependencies working-directory: python - run: make install-iceberg + run: make install-polaris - name: Run integration tests run: make python-integ-test-polaris - name: Collect logs on failure diff --git a/.github/workflows/python-polaris.yml b/.github/workflows/python-polaris.yml new file mode 100644 index 0000000..50130e3 --- /dev/null +++ b/.github/workflows/python-polaris.yml @@ -0,0 +1,64 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Polaris + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/polaris.py + - python/tests/test_polaris.py + - python/pyproject.toml + - .github/workflows/python-polaris.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/polaris.py + - python/tests/test_polaris.py + - python/pyproject.toml + - .github/workflows/python-polaris.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Install dependencies + working-directory: python + run: make install-polaris + - name: Lint + working-directory: python + run: make lint-polaris + - name: Test + working-directory: python + run: make test-polaris diff --git a/docs/src/biglake.md b/docs/src/biglake.md index 093ea88..62b3eed 100644 --- a/docs/src/biglake.md +++ b/docs/src/biglake.md @@ -1,16 +1,9 @@ -# Lance BigLake Namespace +# Google BigLake Metastore -**Google BigLake Metastore** is a fully managed, unified metastore service for data lakes on Google Cloud. +**[Google BigLake Metastore](https://docs.cloud.google.com/biglake/docs/about-blms)** +is a fully managed, unified metastore service for data lakes on Google Cloud. To use Google BigLake Metastore with Lance, you can leverage BigLake's [Iceberg REST Catalog](https://docs.cloud.google.com/biglake/docs/blms-rest-catalog), which exposes an Apache Iceberg REST Catalog-compatible interface. -## Configuration - -Configure your Lance Iceberg namespace to connect to the BigLake Metastore endpoint: - -- **endpoint**: `https://biglake.googleapis.com/iceberg/v1/restcatalog` -- **warehouse**: Your BigLake catalog name in the format `projects/{project}/locations/{location}/catalogs/{catalog}` -- **auth_token**: A valid Google Cloud OAuth2 access token - -All the features and configurations of the [Lance Iceberg REST Catalog Namespace](iceberg.md) apply when using BigLake Metastore. +See [Lance Namespace integration with Iceberg REST Catalog](iceberg.md) for more details. diff --git a/docs/src/dataproc.md b/docs/src/dataproc.md index c7abde4..85860ce 100644 --- a/docs/src/dataproc.md +++ b/docs/src/dataproc.md @@ -1,10 +1,9 @@ -# Lance Dataproc Namespace +# Google Dataproc Metastore -**Google Dataproc Metastore** is a fully managed, +**[Google Dataproc Metastore](https://docs.cloud.google.com/dataproc-metastore/docs/overview)** is a fully managed, highly available, autohealing, serverless metastore that runs on Google Cloud. To use Google Dataproc Metastore with Lance, you can leverage Dataproc's [Hive metastore](https://cloud.google.com/dataproc-metastore/docs/hive-metastore), -which exposes a Hive MetaStore-compatible interface. +which exposes a Apache Hive MetaStore-compatible interface. -Simply configure your Lance Hive namespace to connect to Dataproc's Hive MetaStore endpoint. -All the features and configurations of the Lance Hive Namespace ([V2](hive2.md) or [V3](hive3.md)) apply when using Dataproc Metastore. +See Lance Namespace integration with Hive metastore ([V2](hive2.md) or [V3](hive3.md)) for more details. diff --git a/docs/src/glue.md b/docs/src/glue.md index a6f59cf..f7c0c92 100644 --- a/docs/src/glue.md +++ b/docs/src/glue.md @@ -1,10 +1,13 @@ -# Lance Glue Namespace Implementation Spec +# AWS Glue Data Catalog Lance Namespace Implementation Spec -This document describes how the AWS Glue Data Catalog implements the Lance Namespace client spec. +This document describes how the AWS Glue Data Catalog +implements the Lance Namespace client spec. ## Background -AWS Glue Data Catalog is a fully managed metadata repository that stores structural and operational metadata for data assets. It is compatible with the Apache Hive Metastore API and can be used as a central metadata repository for data lakes. For details on AWS Glue, see the [AWS Glue Data Catalog Documentation](https://docs.aws.amazon.com/glue/). +AWS Glue Data Catalog is a fully managed metadata repository that stores structural and operational metadata for data assets. +It is compatible with the Apache Hive Metastore API and can be used as a central metadata repository for data lakes. +For details on AWS Glue, see the [AWS Glue Data Catalog Documentation](https://docs.aws.amazon.com/glue/latest/dg/manage-catalog.html). ## Namespace Implementation Configuration Properties @@ -22,9 +25,15 @@ The **secret_access_key** property is optional and specifies the AWS secret acce The **session_token** property is optional and specifies the AWS session token for temporary credentials. -The **root** property is optional and specifies the storage root location of the lakehouse on Glue catalog. Default value is the current working directory. +The **assume_role_arn** property is optional and specifies the ARN of the IAM role to assume for Glue operations. -The **storage.*** prefix properties are optional and specify additional storage configurations to access tables (e.g., `storage.region=us-west-2`). +The **assume_role_region** property is optional and specifies the AWS region for the STS client when assuming a role. + +The **assume_role_external_id** property is optional and specifies the external ID for cross-account role assumption. For more details, see [AWS external ID documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html). + +The **assume_role_session_name** property is optional and specifies the session name for the assumed role session. For more details, see [AWS role session name documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname). + +The **assume_role_timeout_sec** property is optional and specifies the duration in seconds for which the assumed role session is valid (default: 3600). At the end of the timeout, a new set of role session credentials will be fetched through the STS client. ### Authentication @@ -33,24 +42,34 @@ The Glue namespace supports multiple authentication methods: 1. **Default AWS credential provider chain**: When no explicit credentials are provided, the client uses the default AWS credential provider chain 2. **Static credentials**: Set `access_key_id` and `secret_access_key` for basic AWS credentials 3. **Session credentials**: Additionally provide `session_token` for temporary AWS credentials +4. **Assume role credentials**: Set `assume_role_arn` to assume an IAM role. Optionally configure `assume_role_region`, `assume_role_external_id`, `assume_role_session_name`, and `assume_role_timeout_sec` to customize the role assumption behavior ## Object Mapping ### Namespace -The **root namespace** is represented by the AWS Glue Data Catalog itself. +AWS Glue Data Catalog supports a recursive catalog structure through the [GetCatalog](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalog.html) and [GetCatalogs](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalogs.html) APIs. +This allows for multi-level namespace hierarchies. + +The **root namespace** is represented by the default AWS Glue Data Catalog, which has a catalog ID of `None` or equal to the caller's AWS account ID. + +A **child catalog** within the root catalog forms a child namespace. The [GetCatalogs](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalogs.html) API supports `ParentCatalogId` parameter to traverse the catalog hierarchy. -A **child namespace** is a database in Glue, forming a 2-level namespace hierarchy. +A **database** within a catalog represents the leaf namespace level. Databases are created within a specific catalog using the `CatalogId` parameter in the [CreateDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_CreateDatabase.html) API. -The **namespace identifier** is the database name. +The **namespace identifier** follows a hierarchical pattern: +- For catalogs: the catalog name (e.g., `my_catalog`) +- For databases: the catalog chain joined with database name using the `$` delimiter (e.g., `catalog$database` or `parent_catalog$child_catalog$database`) -**Namespace properties** are stored in the Glue Database object's parameters map. +**Namespace properties** are stored in: +- Catalog's `Parameters` map for catalog-level namespaces +- Database's `Parameters` map for database-level namespaces ### Table A **table** is represented as a [Table](https://docs.aws.amazon.com/glue/latest/webapi/API_Table.html) object in AWS Glue with `TableType` set to `EXTERNAL_TABLE`. -The **table identifier** is constructed by joining database and table name with the `$` delimiter (e.g., `database$table`). +The **table identifier** is constructed by joining the full namespace path and table name with the `$` delimiter (e.g., `catalog$database$table`). The **table location** is stored in the [`StorageDescriptor.Location`](https://docs.aws.amazon.com/glue/latest/webapi/API_StorageDescriptor.html#Glue-Type-StorageDescriptor-Location) field, pointing to the root location of the Lance table. @@ -60,6 +79,189 @@ The **table location** is stored in the [`StorageDescriptor.Location`](https://d A table in AWS Glue is identified as a Lance table when it meets the following criteria: the `TableType` is `EXTERNAL_TABLE`, and the `Parameters` map contains a key `table_type` with value `lance` (case insensitive). The `StorageDescriptor.Location` must point to a valid Lance table root directory. -## Optimistic Concurrency Control +## Basic Operations + +### CreateNamespace + +Creates a new catalog or database in AWS Glue. + +The implementation: + +1. Parse the namespace identifier to determine if it is a catalog or database level +2. For catalog-level namespace: + - Construct a [CreateCatalog](https://docs.aws.amazon.com/glue/latest/webapi/API_CreateCatalog.html) request with name and properties + - Set the `Parameters` map with the provided namespace properties +3. For database-level namespace: + - Verify the parent catalog exists + - Construct a [CreateDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_CreateDatabase.html) request with database name and `CatalogId` + - Set the `Parameters` map with the provided namespace properties +4. Handle creation mode (CREATE, EXIST_OK, OVERWRITE) appropriately + +**Error Handling:** + +If the namespace already exists and mode is CREATE, return error code `2` (NamespaceAlreadyExists). + +If the parent catalog does not exist, return error code `1` (NamespaceNotFound). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### ListNamespaces + +Lists catalogs or databases in AWS Glue. + +The implementation: + +1. Parse the parent namespace identifier +2. For root namespace (no parent): + - Use [GetCatalogs](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalogs.html) with `IncludeRoot=true` to list all catalogs + - Use `ParentCatalogId` set to account ID and `Recursive=false` for direct children +3. For catalog-level namespace: + - Use [GetDatabases](https://docs.aws.amazon.com/glue/latest/webapi/API_GetDatabases.html) with the catalog's `CatalogId` + - Additionally use [GetCatalogs](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalogs.html) with `ParentCatalogId` to list child catalogs +4. Sort the results and apply pagination using `NextToken` + +**Error Handling:** + +If the parent namespace does not exist, return error code `1` (NamespaceNotFound). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### DescribeNamespace + +Retrieves properties and metadata for a catalog or database. + +The implementation: + +1. Parse the namespace identifier to determine the level +2. For catalog-level namespace: + - Use [GetCatalog](https://docs.aws.amazon.com/glue/latest/webapi/API_GetCatalog.html) with the catalog ID + - Extract properties from the `Parameters` map +3. For database-level namespace: + - Use [GetDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_GetDatabase.html) with the database name and `CatalogId` + - Extract properties from the Database's `Parameters` map + +**Error Handling:** + +If the namespace does not exist, return error code `1` (NamespaceNotFound). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### DropNamespace + +Removes a catalog or database from AWS Glue. Only RESTRICT mode is supported; CASCADE mode is not implemented. + +The implementation: + +1. Parse the namespace identifier to determine the level +2. Check if the namespace exists (handle SKIP mode if not) +3. For catalog-level namespace: + - Verify the catalog has no child catalogs or databases + - Use [DeleteCatalog](https://docs.aws.amazon.com/glue/latest/webapi/API_DeleteCatalog.html) with the catalog ID +4. For database-level namespace: + - Verify the database is empty (no tables) + - Use [DeleteDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_DeleteDatabase.html) with the database name and `CatalogId` + +**Error Handling:** + +If the namespace does not exist and mode is FAIL, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### DeclareTable + +Declares a new Lance table in AWS Glue without creating the underlying data. + +The implementation: + +1. Parse the table identifier to extract catalog, database, and table name +2. Verify the parent namespace (database) exists using [GetDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_GetDatabase.html) +3. Construct a [CreateTable](https://docs.aws.amazon.com/glue/latest/webapi/API_CreateTable.html) request with: + - `CatalogId`: the catalog ID from the namespace + - `DatabaseName`: the database name + - `TableInput.Name`: the table name + - `TableInput.TableType`: `EXTERNAL_TABLE` + - `TableInput.Parameters`: include `table_type=lance` and other properties + - `TableInput.StorageDescriptor.Location`: the specified table location +4. POST the CreateTable request to Glue + +**Error Handling:** + +If the parent namespace does not exist, return error code `1` (NamespaceNotFound). + +If the table already exists, return error code `5` (TableAlreadyExists). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### ListTables + +Lists all Lance tables in a database. + +The implementation: + +1. Parse the namespace identifier to extract catalog and database +2. Verify the namespace exists using [GetDatabase](https://docs.aws.amazon.com/glue/latest/webapi/API_GetDatabase.html) +3. Use [GetTables](https://docs.aws.amazon.com/glue/latest/webapi/API_GetTables.html) with `CatalogId` and `DatabaseName` +4. Filter tables where `Parameters.table_type=lance` (case insensitive) +5. Sort the results and apply pagination using `NextToken` + +**Error Handling:** + +If the namespace does not exist, return error code `1` (NamespaceNotFound). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### DescribeTable + +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. + +The implementation: + +1. Parse the table identifier to extract catalog, database, and table name +2. Use [GetTable](https://docs.aws.amazon.com/glue/latest/webapi/API_GetTable.html) with `CatalogId`, `DatabaseName`, and `Name` +3. Validate that the table is a Lance table (check `Parameters.table_type=lance`) +4. Return the table location from `StorageDescriptor.Location` and storage_options from `Parameters` + +**Error Handling:** + +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If access is denied, return error code `16` (Forbidden). + +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). + +### DeregisterTable + +Removes a Lance table registration from AWS Glue without deleting the underlying data. + +The implementation: + +1. Parse the table identifier to extract catalog, database, and table name +2. Use [GetTable](https://docs.aws.amazon.com/glue/latest/webapi/API_GetTable.html) to retrieve and validate the table is a Lance table +3. Use [DeleteTable](https://docs.aws.amazon.com/glue/latest/webapi/API_DeleteTable.html) with `CatalogId`, `DatabaseName`, and `Name` +4. The underlying Lance table data at `StorageDescriptor.Location` is not deleted + +**Error Handling:** + +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If access is denied, return error code `16` (Forbidden). -Updates to Lance tables in AWS Glue should use the `VersionId` for conditional updates through the [UpdateTable](https://docs.aws.amazon.com/glue/latest/webapi/API_UpdateTable.html) API. If the `VersionId` does not match the expected version, the update fails to prevent concurrent modification conflicts. +If the Glue service is unavailable, return error code `17` (ServiceUnavailable). diff --git a/docs/src/hive2.md b/docs/src/hive2.md index bb4e325..cced4c5 100644 --- a/docs/src/hive2.md +++ b/docs/src/hive2.md @@ -87,19 +87,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DropNamespace -Removes a database from HMS. +Removes a database from HMS. Only RESTRICT mode is supported; CASCADE mode is not implemented. The implementation: 1. Parse the namespace identifier (database name) 2. Check if the namespace exists (handle SKIP mode if not) -3. For RESTRICT behavior: verify the namespace is empty (no tables) -4. For CASCADE behavior: drop all tables first -5. Drop the database from HMS +3. Verify the namespace is empty (no tables) +4. Drop the database from HMS **Error Handling:** -If the namespace does not exist and mode is FAIL, return error code `1` (NamespaceNotFound). If the namespace is not empty and behavior is RESTRICT, return error code `3` (NamespaceNotEmpty). If the HMS connection fails, return error code `17` (ServiceUnavailable). +If the namespace does not exist and mode is FAIL, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If the HMS connection fails, return error code `17` (ServiceUnavailable). ### DeclareTable @@ -136,18 +139,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DescribeTable -Retrieves metadata for a Lance table. +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. The implementation: 1. Parse the table identifier 2. Retrieve the Table object from HMS 3. Validate that it is a Lance table (check `table_type=lance`) -4. Return the table location and properties +4. Return the table location from `storageDescriptor.location` and storage_options from `parameters` **Error Handling:** -If the table does not exist, return error code `4` (TableNotFound). If the table is not a Lance table, return error code `13` (InvalidInput). If the HMS connection fails, return error code `17` (ServiceUnavailable). +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If the HMS connection fails, return error code `17` (ServiceUnavailable). ### DeregisterTable diff --git a/docs/src/hive3.md b/docs/src/hive3.md index 63a9b79..99f5746 100644 --- a/docs/src/hive3.md +++ b/docs/src/hive3.md @@ -90,19 +90,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DropNamespace -Removes a namespace from HMS. +Removes a namespace from HMS. Only RESTRICT mode is supported; CASCADE mode is not implemented. The implementation: 1. Parse the namespace identifier 2. Check if the namespace exists (handle SKIP mode if not) -3. For RESTRICT behavior: verify the namespace is empty (no child namespaces or tables) -4. For CASCADE behavior: recursively drop all child objects first -5. Drop the catalog or database from HMS +3. Verify the namespace is empty (no child namespaces or tables) +4. Drop the catalog or database from HMS **Error Handling:** -If the namespace does not exist and mode is FAIL, return error code `1` (NamespaceNotFound). If the namespace is not empty and behavior is RESTRICT, return error code `3` (NamespaceNotEmpty). If the HMS connection fails, return error code `17` (ServiceUnavailable). +If the namespace does not exist and mode is FAIL, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If the HMS connection fails, return error code `17` (ServiceUnavailable). ### DeclareTable @@ -139,18 +142,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DescribeTable -Retrieves metadata for a Lance table. +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. The implementation: 1. Parse the table identifier 2. Retrieve the Table object from HMS 3. Validate that it is a Lance table (check `table_type=lance`) -4. Return the table location and properties +4. Return the table location from `storageDescriptor.location` and storage_options from `parameters` **Error Handling:** -If the table does not exist, return error code `4` (TableNotFound). If the table is not a Lance table, return error code `13` (InvalidInput). If the HMS connection fails, return error code `17` (ServiceUnavailable). +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If the HMS connection fails, return error code `17` (ServiceUnavailable). ### DeregisterTable diff --git a/docs/src/iceberg.md b/docs/src/iceberg.md index fa15609..734684e 100644 --- a/docs/src/iceberg.md +++ b/docs/src/iceberg.md @@ -101,7 +101,7 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DropNamespace -Removes a namespace from the Iceberg catalog. +Removes a namespace from the Iceberg catalog. Only RESTRICT mode is supported; CASCADE mode is not implemented. The implementation: @@ -110,7 +110,11 @@ The implementation: **Error Handling:** -If the namespace does not exist, return error code `1` (NamespaceNotFound). If the namespace is not empty, return error code `3` (NamespaceNotEmpty). If the server returns an error, return error code `18` (Internal). +If the namespace does not exist, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If the server returns an error, return error code `18` (Internal). ### DeclareTable @@ -148,18 +152,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DescribeTable -Retrieves metadata for a Lance table. +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. The implementation: 1. Parse the table identifier to extract namespace and table name 2. GET `/v1/{prefix}/namespaces/{namespace}/tables/{table}` 3. Verify the table has `table_type=lance` property -4. Return the table location and properties +4. Return the table location and storage_options from `properties` **Error Handling:** -If the table does not exist, return error code `4` (TableNotFound). If the table is not a Lance table, return error code `13` (InvalidInput). If the server returns an error, return error code `18` (Internal). +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If the server returns an error, return error code `18` (Internal). ### DeregisterTable diff --git a/docs/src/polaris.md b/docs/src/polaris.md index de52d30..68843ae 100644 --- a/docs/src/polaris.md +++ b/docs/src/polaris.md @@ -94,7 +94,7 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DropNamespace -Removes a namespace from Polaris. +Removes a namespace from Polaris. Only RESTRICT mode is supported; CASCADE mode is not implemented. The implementation: @@ -103,7 +103,11 @@ The implementation: **Error Handling:** -If the namespace does not exist, return error code `1` (NamespaceNotFound). If the namespace is not empty, return error code `3` (NamespaceNotEmpty). If the server returns an error, return error code `18` (Internal). +If the namespace does not exist, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If the server returns an error, return error code `18` (Internal). ### DeclareTable @@ -141,18 +145,22 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DescribeTable -Retrieves metadata for a Lance table. +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. The implementation: 1. Parse the table identifier to extract namespace and table name 2. GET `/namespaces/{namespace}/generic-tables/{table}` 3. Verify the table format is `lance` -4. Return the table location, properties, and optional doc as comment +4. Return the table location from `base-location` and storage_options from `properties` **Error Handling:** -If the table does not exist, return error code `4` (TableNotFound). If the table format is not `lance`, return error code `13` (InvalidInput). If the server returns an error, return error code `18` (Internal). +If the table does not exist, return error code `4` (TableNotFound). + +If the table format is not `lance`, return error code `13` (InvalidInput). + +If the server returns an error, return error code `18` (Internal). ### DeregisterTable diff --git a/docs/src/unity.md b/docs/src/unity.md index ed27665..3ec97b5 100644 --- a/docs/src/unity.md +++ b/docs/src/unity.md @@ -106,18 +106,21 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DropNamespace -Removes a schema from Unity Catalog. +Removes a schema from Unity Catalog. Only RESTRICT mode is supported; CASCADE mode is not implemented. The implementation: 1. Parse the namespace identifier (must be 2-level: catalog.schema) 2. Verify the catalog matches the configured catalog -3. For CASCADE behavior: add `force=true` parameter -4. DELETE `/schemas/{catalog}.{schema}` +3. DELETE `/schemas/{catalog}.{schema}` **Error Handling:** -If the namespace does not exist, return error code `1` (NamespaceNotFound). If the namespace is not empty and behavior is RESTRICT, return error code `3` (NamespaceNotEmpty). If the server returns an error, return error code `18` (Internal). +If the namespace does not exist, return error code `1` (NamespaceNotFound). + +If the namespace is not empty, return error code `3` (NamespaceNotEmpty). + +If the server returns an error, return error code `18` (Internal). ### DeclareTable @@ -160,7 +163,7 @@ If the namespace does not exist, return error code `1` (NamespaceNotFound). If t ### DescribeTable -Retrieves metadata for a Lance table. +Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is supported. When `load_detailed_metadata=false`, only the table location and storage_options are returned; other fields (version, table_uri, schema, stats) are null. The implementation: @@ -168,11 +171,15 @@ The implementation: 2. Verify the catalog matches the configured catalog 3. GET `/tables/{catalog}.{schema}.{table}` 4. Verify the table is a Lance table (check `properties.table_type=lance`) -5. Return the table location, properties, and schema +5. Return the table location from `storage_location` and storage_options from `properties` **Error Handling:** -If the table does not exist, return error code `4` (TableNotFound). If the table is not a Lance table, return error code `13` (InvalidInput). If the server returns an error, return error code `18` (Internal). +If the table does not exist, return error code `4` (TableNotFound). + +If the table is not a Lance table, return error code `13` (InvalidInput). + +If the server returns an error, return error code `18` (Internal). ### DeregisterTable diff --git a/java/lance-namespace-glue/pom.xml b/java/lance-namespace-glue/pom.xml index 142154f..d3dffa8 100644 --- a/java/lance-namespace-glue/pom.xml +++ b/java/lance-namespace-glue/pom.xml @@ -26,6 +26,10 @@ org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client diff --git a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java index 7f2b42e..0e13300 100644 --- a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java +++ b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java @@ -13,16 +13,16 @@ */ package org.lance.namespace.glue; -import com.lancedb.lance.Dataset; -import com.lancedb.lance.WriteParams; +import org.lance.Dataset; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; @@ -31,8 +31,6 @@ import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; @@ -42,17 +40,12 @@ import org.lance.namespace.model.RegisterTableRequest; import org.lance.namespace.model.RegisterTableResponse; import org.lance.namespace.model.TableExistsRequest; -import org.lance.namespace.util.ArrowIpcUtil; -import org.lance.namespace.util.JsonArrowSchemaConverter; -import org.lance.namespace.util.OpenDalUtil; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.arrow.memory.BufferAllocator; -import org.apache.arrow.vector.types.pojo.Schema; -import org.apache.opendal.Operator; import software.amazon.awssdk.services.glue.GlueClient; import software.amazon.awssdk.services.glue.model.AlreadyExistsException; import software.amazon.awssdk.services.glue.model.CreateDatabaseRequest; @@ -74,7 +67,6 @@ import software.amazon.awssdk.services.glue.model.TableInput; import java.io.Closeable; -import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Set; @@ -158,23 +150,19 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { String namespaceName = namespaceFromId(request.getId()); - CreateNamespaceRequest.ModeEnum mode = - request.getMode() != null ? request.getMode() : CreateNamespaceRequest.ModeEnum.CREATE; + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "create"; Map params = request.getProperties() != null ? request.getProperties() : ImmutableMap.of(); boolean namespaceExists = databaseExists(namespaceName); - switch (mode) { - case EXIST_OK: - if (namespaceExists) { - return describeNamespaceAsCreateResponse(namespaceName); - } - break; - case OVERWRITE: - if (namespaceExists) { - deleteDatabase(namespaceName); - } - break; + if ("exist_ok".equals(mode) || "existok".equals(mode)) { + if (namespaceExists) { + return describeNamespaceAsCreateResponse(namespaceName); + } + } else if ("overwrite".equals(mode)) { + if (namespaceExists) { + deleteDatabase(namespaceName); + } } try { @@ -185,7 +173,7 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { .build()); return new CreateNamespaceResponse().properties(params); } catch (AlreadyExistsException e) { - if (mode == CreateNamespaceRequest.ModeEnum.EXIST_OK) { + if ("exist_ok".equals(mode) || "existok".equals(mode)) { return describeNamespaceAsCreateResponse(namespaceName); } throw GlueToLanceErrorConverter.conflict(e, "Namespace already exists: %s", namespaceName); @@ -199,32 +187,17 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { String namespaceName = namespaceFromId(request.getId()); - DropNamespaceRequest.ModeEnum mode = - request.getMode() != null ? request.getMode() : DropNamespaceRequest.ModeEnum.FAIL; - DropNamespaceRequest.BehaviorEnum behavior = - request.getBehavior() != null - ? request.getBehavior() - : DropNamespaceRequest.BehaviorEnum.RESTRICT; + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; if (!databaseExists(namespaceName)) { - if (mode == DropNamespaceRequest.ModeEnum.SKIP) { + if ("skip".equals(mode)) { return new DropNamespaceResponse(); } - throw LanceNamespaceException.badRequest( - "Namespace not found: " + namespaceName, - "NAMESPACE_NOT_FOUND", - namespaceName, - "The requested namespace does not exist"); + throw new NamespaceNotFoundException( + "Namespace not found: " + namespaceName, "NAMESPACE_NOT_FOUND", namespaceName); } - switch (behavior) { - case CASCADE: - deleteAllTables(namespaceName); - break; - case RESTRICT: - ensureNamespaceEmpty(namespaceName); - break; - } + ensureNamespaceEmpty(namespaceName); deleteDatabase(namespaceName); return new DropNamespaceResponse(); @@ -291,15 +264,17 @@ public RegisterTableResponse registerTable(RegisterTableRequest request) { String namespaceName = request.getId().get(0); String tableName = request.getId().get(1); - if (request.getLocation().isEmpty()) { - throw LanceNamespaceException.badRequest("Table location is required", "BAD_REQUEST", "", ""); + if (request.getLocation() == null || request.getLocation().isEmpty()) { + throw new InvalidInputException("Table location is required", "BAD_REQUEST", ""); } - String location = OpenDalUtil.stripTrailingSlash(request.getLocation()); - RegisterTableRequest.ModeEnum mode = - request.getMode() != null ? request.getMode() : RegisterTableRequest.ModeEnum.CREATE; + String location = request.getLocation(); + location = + location != null && location.endsWith("/") + ? location.substring(0, location.length() - 1) + : location; + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "create"; - if (mode == RegisterTableRequest.ModeEnum.OVERWRITE) { - // If table exists, delete its Glue Table (ignore if missing) + if ("overwrite".equals(mode)) { deleteGlueTable(namespaceName, tableName, false); } @@ -331,10 +306,11 @@ public RegisterTableResponse registerTable(RegisterTableRequest request) { response.setProperties(request.getProperties()); return response; } catch (AlreadyExistsException e) { - throw GlueToLanceErrorConverter.conflict( + throw GlueToLanceErrorConverter.tableConflict( e, "Table already exists: %s.%s", namespaceName, tableName); } catch (EntityNotFoundException e) { - throw GlueToLanceErrorConverter.notFound(e, "Namespace not found: %s", namespaceName); + throw GlueToLanceErrorConverter.namespaceNotFound( + e, "Namespace not found: %s", namespaceName); } catch (GlueException e) { throw GlueToLanceErrorConverter.serverError( e, "Failed to register table: %s.%s", namespaceName, tableName); @@ -371,98 +347,7 @@ public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { } } - @Override - public CreateTableResponse createTable(CreateTableRequest request, byte[] requestData) { - // Validate that requestData is a valid Arrow IPC stream - if (requestData == null || requestData.length == 0) { - throw LanceNamespaceException.badRequest( - "Request data (Arrow IPC stream) is required for createTable", - "INVALID_REQUEST", - String.join(".", request.getId()), - "Arrow IPC stream data is required"); - } - - validateTableId(request.getId()); - String namespaceName = request.getId().get(0); - String tableName = request.getId().get(1); - - String location = request.getLocation(); - if (location == null || location.isEmpty()) { - location = getDefaultTableLocation(namespaceName, tableName); - } - - try { - Map params = Maps.newHashMap(); - if (request.getProperties() != null) { - params.putAll(request.getProperties()); - } - params.put(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE); - params.put(MANAGED_BY_PROP, params.getOrDefault(MANAGED_BY_PROP, STORAGE_VALUE)); - params.put(VERSION_PROP, "1"); - - // Extract schema from Arrow IPC stream - JsonArrowSchema jsonSchema; - try { - jsonSchema = ArrowIpcUtil.extractSchemaFromIpc(requestData); - } catch (IOException e) { - throw LanceNamespaceException.badRequest( - "Invalid Arrow IPC stream: " + e.getMessage(), - "INVALID_ARROW_IPC", - namespaceName + "." + tableName, - "Failed to extract schema from Arrow IPC stream"); - } - Schema schema = JsonArrowSchemaConverter.convertToArrowSchema(jsonSchema); - - WriteParams writeParams = - new WriteParams.Builder() - .withMode(WriteParams.WriteMode.CREATE) - .withStorageOptions(config.getStorageOptions()) - .build(); - - try { - Dataset.create(allocator, location, schema, writeParams); - } catch (Exception e) { - throw LanceNamespaceException.serverError( - "Failed to create Lance dataset at location: " + location, - "DATASET_CREATE_ERROR", - location, - "An error occurred while creating the Lance dataset: " + e.getMessage()); - } - - TableInput tableInput = - TableInput.builder() - .name(tableName) - .storageDescriptor( - StorageDescriptor.builder().location(location).parameters(params).build()) - .parameters(params) - .build(); - - glueClient.createTable( - software.amazon.awssdk.services.glue.model.CreateTableRequest.builder() - .catalogId(config.catalogId()) - .databaseName(namespaceName) - .tableInput(tableInput) - .build()); - - CreateTableResponse response = new CreateTableResponse(); - response.setLocation(location); - response.setVersion(1L); - response.setProperties(request.getProperties()); - response.setStorageOptions(config.getStorageOptions()); - return response; - } catch (GlueException e) { - safeDropDataset(location); - if (e instanceof AlreadyExistsException) { - throw GlueToLanceErrorConverter.conflict( - e, "Table already exists: %s.%s", namespaceName, tableName); - } else if (e instanceof EntityNotFoundException) { - throw GlueToLanceErrorConverter.notFound(e, "Namespace not found: %s", namespaceName); - } else { - throw GlueToLanceErrorConverter.serverError( - e, "Failed to create table: %s.%s", namespaceName, tableName); - } - } - } + // Removed: createTable(CreateTableRequest, byte[]) - using default implementation from interface @Override public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { @@ -477,11 +362,8 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request try { Map params = Maps.newHashMap(); - if (request.getProperties() != null) { - params.putAll(request.getProperties()); - } params.put(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE); - params.put(MANAGED_BY_PROP, params.getOrDefault(MANAGED_BY_PROP, STORAGE_VALUE)); + params.put(MANAGED_BY_PROP, STORAGE_VALUE); TableInput tableInput = TableInput.builder() @@ -500,53 +382,21 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request CreateEmptyTableResponse response = new CreateEmptyTableResponse(); response.setLocation(location); - response.setProperties(request.getProperties()); response.setStorageOptions(config.getStorageOptions()); return response; } catch (AlreadyExistsException e) { - throw GlueToLanceErrorConverter.conflict( + throw GlueToLanceErrorConverter.tableConflict( e, "Table already exists: %s.%s", namespaceName, tableName); } catch (EntityNotFoundException e) { - throw GlueToLanceErrorConverter.notFound(e, "Namespace not found: %s", namespaceName); + throw GlueToLanceErrorConverter.namespaceNotFound( + e, "Namespace not found: %s", namespaceName); } catch (GlueException e) { throw GlueToLanceErrorConverter.serverError( e, "Failed to create empty table: %s.%s", namespaceName, tableName); } } - @Override - public DropTableResponse dropTable(DropTableRequest request) { - validateTableId(request.getId()); - String namespaceName = request.getId().get(0); - String tableName = request.getId().get(1); - - Table table = getGlueTable(namespaceName, tableName); - ensureLanceTable(table); - String tableLocation = null; - if (table.storageDescriptor() != null && table.storageDescriptor().location() != null) { - tableLocation = OpenDalUtil.stripTrailingSlash(table.storageDescriptor().location()); - } - - try { - Dataset.drop(tableLocation, config.getStorageOptions()); - } catch (Exception e) { - // Log warning but continue with Glue metadata deletion - throw LanceNamespaceException.serverError( - "Failed to drop Lance dataset at location: " + tableLocation, - "DATASET_DROP_ERROR", - tableLocation, - e.getMessage()); - } - - deleteGlueTable(namespaceName, tableName, false); - DropTableResponse response = new DropTableResponse(); - response.setId(request.getId()); - response.setLocation(tableLocation); - if (table.parameters() != null && !table.parameters().isEmpty()) { - response.setProperties(table.parameters()); - } - return response; - } + // Removed: dropTable(DropTableRequest) - using default implementation from interface @Override public void tableExists(TableExistsRequest request) { @@ -561,44 +411,39 @@ public void tableExists(TableExistsRequest request) { private void validateParent(List id) { if (id != null && id.size() > 1) { String instance = String.join("/", id); - throw LanceNamespaceException.badRequest( + throw new InvalidInputException( "Glue does not support nested namespaces. Found nested path: " + String.join("/", id), "BAD_REQUEST", - instance, - "Nested namespaces must have only one parent"); + instance); } } private String namespaceFromId(List id) { if (id == null || id.isEmpty()) { - throw LanceNamespaceException.badRequest( - "Namespace identifier cannot be null or empty", "BAD_REQUEST", "", ""); + throw new InvalidInputException("Namespace identifier cannot be null or empty"); } validateParent(id); String namespace = id.get(0); if (namespace == null || namespace.isEmpty()) { - throw LanceNamespaceException.badRequest( - "Namespace name cannot be empty", "BAD_REQUEST", "", ""); + throw new InvalidInputException("Namespace name cannot be empty"); } return namespace; } private void validateTableId(List id) { if (id == null || id.size() != 2) { - throw LanceNamespaceException.badRequest( + throw new InvalidInputException( "Table identifier must contain exactly 2 elements, but got " + id, "BAD_REQUEST", - id != null ? String.join("/", id) : "", - "Expected format: [namespace, table]"); + id != null ? String.join("/", id) : ""); } if (id.get(0) == null || id.get(0).isEmpty()) { - throw LanceNamespaceException.badRequest( - "Namespace name cannot be empty", "BAD_REQUEST", "", ""); + throw new InvalidInputException("Namespace name cannot be empty"); } if (id.get(1) == null || id.get(1).isEmpty()) { - throw LanceNamespaceException.badRequest("Table name cannot be empty", "BAD_REQUEST", "", ""); + throw new InvalidInputException("Table name cannot be empty"); } } @@ -661,7 +506,11 @@ private DatabaseInput buildDatabaseInput(String namespaceName, Map properties) { this.accessKeyId = properties.get(ACCESS_KEY_ID); this.secretAccessKey = properties.get(SECRET_ACCESS_KEY); this.sessionToken = properties.get(SESSION_TOKEN); - this.storageOptions = PropertyUtil.propertiesWithPrefix(properties, STORAGE_OPTIONS_PREFIX); + + // Inline PropertyUtil.propertiesWithPrefix + Map filteredStorageOptions = new HashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + if (entry.getKey().startsWith(STORAGE_OPTIONS_PREFIX)) { + filteredStorageOptions.put( + entry.getKey().substring(STORAGE_OPTIONS_PREFIX.length()), entry.getValue()); + } + } + this.storageOptions = filteredStorageOptions; + + // Inline PropertyUtil.propertyAsString and OpenDalUtil.stripTrailingSlash + String rootValue = properties.getOrDefault(ROOT, ROOT_DEFAULT); this.root = - OpenDalUtil.stripTrailingSlash( - PropertyUtil.propertyAsString(properties, ROOT, ROOT_DEFAULT)); + rootValue != null && rootValue.endsWith("/") + ? rootValue.substring(0, rootValue.length() - 1) + : rootValue; } public String catalogId() { diff --git a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueToLanceErrorConverter.java b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueToLanceErrorConverter.java index 2a0a7c8..8c15914 100644 --- a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueToLanceErrorConverter.java +++ b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueToLanceErrorConverter.java @@ -13,7 +13,12 @@ */ package org.lance.namespace.glue; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.LanceNamespaceException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import software.amazon.awssdk.services.glue.model.GlueException; @@ -22,27 +27,30 @@ public class GlueToLanceErrorConverter { private GlueToLanceErrorConverter() {} public static LanceNamespaceException notFound(GlueException e, String message, Object... args) { - return LanceNamespaceException.notFound( - String.format(message, args), - e.getMessage().getClass().getSimpleName(), - e.requestId(), - e.getMessage()); + return new TableNotFoundException( + String.format(message, args), e.getClass().getSimpleName(), e.requestId()); + } + + public static LanceNamespaceException namespaceNotFound( + GlueException e, String message, Object... args) { + return new NamespaceNotFoundException( + String.format(message, args), e.getClass().getSimpleName(), e.requestId()); } public static LanceNamespaceException conflict(GlueException e, String message, Object... args) { - return LanceNamespaceException.notFound( - String.format(message, args), - e.getMessage().getClass().getSimpleName(), - e.requestId(), - e.getMessage()); + return new NamespaceAlreadyExistsException( + String.format(message, args), e.getClass().getSimpleName(), e.requestId()); + } + + public static LanceNamespaceException tableConflict( + GlueException e, String message, Object... args) { + return new TableAlreadyExistsException( + String.format(message, args), e.getClass().getSimpleName(), e.requestId()); } public static LanceNamespaceException serverError( GlueException e, String message, Object... args) { - return LanceNamespaceException.serverError( - String.format(message, args), - e.getMessage().getClass().getSimpleName(), - e.requestId(), - e.getMessage()); + return new InternalException( + String.format(message, args), e.getClass().getSimpleName(), e.requestId()); } } diff --git a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java index 1979280..1e43474 100644 --- a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java +++ b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java @@ -13,12 +13,9 @@ */ package org.lance.namespace.glue; -import com.lancedb.lance.Dataset; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; @@ -26,11 +23,6 @@ import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; -import org.lance.namespace.model.JsonArrowDataType; -import org.lance.namespace.model.JsonArrowField; -import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -50,7 +42,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.io.TempDir; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import software.amazon.awssdk.services.glue.GlueClient; @@ -77,22 +68,15 @@ import software.amazon.awssdk.services.glue.model.Table; import software.amazon.awssdk.services.glue.model.TableVersion; -import java.io.File; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import static org.lance.namespace.glue.GlueNamespace.LANCE_TABLE_TYPE_VALUE; -import static org.lance.namespace.glue.GlueNamespace.TABLE_TYPE_PROP; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.lance.namespace.glue.GlueNamespace.LANCE_TABLE_TYPE_VALUE; +import static org.lance.namespace.glue.GlueNamespace.TABLE_TYPE_PROP; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -106,7 +90,6 @@ public class TestGlueNamespace { private GlueNamespace glueNamespace; private static BufferAllocator allocator; - @TempDir Path tempDir; @BeforeAll public static void setUpAll() { @@ -212,7 +195,7 @@ public void testCreateNamespaceWithCreateMode() { CreateNamespaceRequest request = new CreateNamespaceRequest() .id(ImmutableList.of("test")) - .mode(CreateNamespaceRequest.ModeEnum.CREATE) + .mode("Create") .properties(ImmutableMap.of("location", "s3://bucket/test")); // Mock namespace doesn't exist @@ -231,9 +214,7 @@ public void testCreateNamespaceWithCreateMode() { public void testCreateNamespaceWithCreateModeAlreadyExists() { String namespaceName = "existing"; CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.CREATE); + new CreateNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Create"); // Mock namespace exists Database existingDatabase = Database.builder().name(namespaceName).build(); @@ -252,9 +233,7 @@ public void testCreateNamespaceWithCreateModeAlreadyExists() { public void testCreateNamespaceWithExistOkModeNamespaceExists() { String namespaceName = "existing"; CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.EXIST_OK); + new CreateNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("ExistOk"); Database existingDatabase = Database.builder() @@ -281,7 +260,7 @@ public void testCreateNamespaceWithExistOkModeNamespaceDoesNotExist() { CreateNamespaceRequest request = new CreateNamespaceRequest() .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.EXIST_OK) + .mode("ExistOk") .properties(ImmutableMap.of("key", "val")); when(glue.getDatabase(any(GetDatabaseRequest.class))) @@ -299,9 +278,7 @@ public void testCreateNamespaceWithExistOkModeNamespaceDoesNotExist() { public void testCreateNamespaceWithOverwriteMode() { String namespaceName = "overwrite"; CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.OVERWRITE); + new CreateNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Overwrite"); // Mock namespace exists Database existingDatabase = Database.builder().name(namespaceName).build(); @@ -325,9 +302,7 @@ public void testCreateNamespaceWithOverwriteMode() { public void testCreateNamespaceWithOverwriteModeNamespaceDoesNotExist() { String namespaceName = "overwrite"; CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.OVERWRITE); + new CreateNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Overwrite"); // Mock namespace doesn't exist when(glue.getDatabase(any(GetDatabaseRequest.class))) @@ -347,7 +322,7 @@ public void testBasicCreateNamespaceWithLocationAndDescription() { CreateNamespaceRequest request = new CreateNamespaceRequest() .id(ImmutableList.of(namespaceName)) - .mode(CreateNamespaceRequest.ModeEnum.CREATE) + .mode("Create") .properties( ImmutableMap.of( "location", @@ -374,8 +349,7 @@ public void testBasicCreateNamespaceWithLocationAndDescription() { @Test public void testCreateNamespaceWithNullName() { - CreateNamespaceRequest request = - new CreateNamespaceRequest().mode(CreateNamespaceRequest.ModeEnum.CREATE); + CreateNamespaceRequest request = new CreateNamespaceRequest().mode("Create"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.createNamespace(request)); } @@ -383,9 +357,7 @@ public void testCreateNamespaceWithNullName() { @Test public void testCreateNamespaceWithEmptyName() { CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of("")) - .mode(CreateNamespaceRequest.ModeEnum.CREATE); + new CreateNamespaceRequest().id(ImmutableList.of("")).mode("Create"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.createNamespace(request)); } @@ -393,9 +365,7 @@ public void testCreateNamespaceWithEmptyName() { @Test public void testCreateNamespaceWithNestedParent() { CreateNamespaceRequest request = - new CreateNamespaceRequest() - .id(ImmutableList.of("parent", "ns1")) - .mode(CreateNamespaceRequest.ModeEnum.CREATE); + new CreateNamespaceRequest().id(ImmutableList.of("parent", "ns1")).mode("Create"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.createNamespace(request)); } @@ -404,9 +374,7 @@ public void testCreateNamespaceWithNestedParent() { public void testDropNamespaceWithFailModeExists() { String namespaceName = "ns1"; DropNamespaceRequest request = - new DropNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(DropNamespaceRequest.ModeEnum.FAIL); + new DropNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Fail"); // Mock database exists Database database = Database.builder().name(namespaceName).build(); @@ -431,9 +399,7 @@ public void testDropNamespaceWithFailModeExists() { public void testDropNamespaceWithFailModeDoesNotExist() { String namespaceName = "nonexistent"; DropNamespaceRequest request = - new DropNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(DropNamespaceRequest.ModeEnum.FAIL); + new DropNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Fail"); when(glue.getDatabase(any(GetDatabaseRequest.class))) .thenThrow(EntityNotFoundException.builder().build()); @@ -445,9 +411,7 @@ public void testDropNamespaceWithFailModeDoesNotExist() { public void testDropNamespaceWithSkipModeDoesNotExist() { String namespaceName = "nonexistent"; DropNamespaceRequest request = - new DropNamespaceRequest() - .id(ImmutableList.of(namespaceName)) - .mode(DropNamespaceRequest.ModeEnum.SKIP); + new DropNamespaceRequest().id(ImmutableList.of(namespaceName)).mode("Skip"); when(glue.getDatabase(any(GetDatabaseRequest.class))) .thenThrow(EntityNotFoundException.builder().build()); @@ -463,8 +427,8 @@ public void testDropNamespaceWithRestrictBehaviorHasTables() { DropNamespaceRequest request = new DropNamespaceRequest() .id(ImmutableList.of(namespaceName)) - .mode(DropNamespaceRequest.ModeEnum.FAIL) - .behavior(DropNamespaceRequest.BehaviorEnum.RESTRICT); + .mode("Fail") + .behavior("Restrict"); Database database = Database.builder().name(namespaceName).build(); Table table = Table.builder().name("table").build(); @@ -484,8 +448,8 @@ public void testDropNamespaceWithCascadeBehaviorHasTables() { DropNamespaceRequest request = new DropNamespaceRequest() .id(ImmutableList.of(namespaceName)) - .mode(DropNamespaceRequest.ModeEnum.FAIL) - .behavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + .mode("Fail") + .behavior("Cascade"); Database database = Database.builder().name(namespaceName).build(); Table table1 = Table.builder().name("table1").build(); @@ -509,81 +473,15 @@ public void testDropNamespaceWithCascadeBehaviorHasTables() { verify(glue).deleteDatabase(any(DeleteDatabaseRequest.class)); } - @Test - public void testDeleteAllTablesDropsLanceAndNonLance() throws Exception { - String namespace = "ns1"; - Path nsDir = tempDir.resolve(namespace); - Path lanceTable = nsDir.resolve("tbl1"); - - // First create a lance table - org.lance.namespace.model.CreateTableRequest createReq = - new org.lance.namespace.model.CreateTableRequest() - .id(ImmutableList.of(namespace, "tbl1")) - .location(lanceTable.toString()); - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - glueNamespace.createTable(createReq, createTestArrowData()); - - // Create a mocked directory of another table with data - Path nonLanceTable = nsDir.resolve("tbl2"); - Files.createDirectories(nonLanceTable); - Files.write(nonLanceTable.resolve("foo.metadata"), "bar".getBytes()); - assertTrue(Files.exists(nonLanceTable.resolve("foo.metadata"))); - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenReturn( - GetDatabaseResponse.builder() - .database(Database.builder().name(namespace).build()) - .build()); - - // Mock delete glue calls - Table t1 = - Table.builder() - .databaseName(namespace) - .name("tbl1") - .storageDescriptor(StorageDescriptor.builder().location(lanceTable.toString()).build()) - .parameters(ImmutableMap.of(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE)) - .build(); - Table t2 = - Table.builder() - .databaseName(namespace) - .name("tbl2") - .storageDescriptor( - StorageDescriptor.builder().location(nonLanceTable.toString()).build()) - .build(); - - when(glue.getTables(any(GetTablesRequest.class))) - .thenReturn(GetTablesResponse.builder().tableList(t1, t2).build()); - when(glue.deleteTable(any(DeleteTableRequest.class))) - .thenReturn(DeleteTableResponse.builder().build()); - when(glue.deleteDatabase(any(DeleteDatabaseRequest.class))) - .thenReturn(DeleteDatabaseResponse.builder().build()); - - // Drop with cascade - DropNamespaceRequest drop = - new DropNamespaceRequest() - .id(ImmutableList.of(namespace)) - .mode(DropNamespaceRequest.ModeEnum.FAIL) - .behavior(DropNamespaceRequest.BehaviorEnum.CASCADE); - glueNamespace.dropNamespace(drop); - - assertFalse(Files.exists(lanceTable), "Lance dataset directory should have been deleted"); - assertFalse(Files.exists(nonLanceTable), "Non-Lance directory should have been deleted"); - } - @Test public void testDropNamespaceWithNullName() { - DropNamespaceRequest request = - new DropNamespaceRequest().mode(DropNamespaceRequest.ModeEnum.FAIL); + DropNamespaceRequest request = new DropNamespaceRequest().mode("Fail"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.dropNamespace(request)); } @Test public void testDropNamespaceWithEmptyName() { - DropNamespaceRequest request = - new DropNamespaceRequest() - .id(ImmutableList.of("")) - .mode(DropNamespaceRequest.ModeEnum.FAIL); + DropNamespaceRequest request = new DropNamespaceRequest().id(ImmutableList.of("")).mode("Fail"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.dropNamespace(request)); } @@ -591,9 +489,7 @@ public void testDropNamespaceWithEmptyName() { @Test public void testDropNamespaceWithNestedParent() { DropNamespaceRequest request = - new DropNamespaceRequest() - .id(ImmutableList.of("parent", "ns1")) - .mode(DropNamespaceRequest.ModeEnum.FAIL); + new DropNamespaceRequest().id(ImmutableList.of("parent", "ns1")).mode("Fail"); assertThrows(LanceNamespaceException.class, () -> glueNamespace.dropNamespace(request)); } @@ -822,7 +718,7 @@ public void testRegisterTableWithOverwrite() { glueNamespace.registerTable(req); // Now overwrite - req.setMode(RegisterTableRequest.ModeEnum.OVERWRITE); + req.setMode("Overwrite"); glueNamespace.registerTable(req); } @@ -948,227 +844,4 @@ public void testTableExistsInvalidId() { assertThrows(LanceNamespaceException.class, () -> glueNamespace.tableExists(req)); } - - @Test - public void testBasicCreateTable() { - String location = tempDir.resolve("ns1/tbl").toString(); - CreateTableRequest request = - new CreateTableRequest().id(ImmutableList.of("ns1", "tbl")).location(location); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - CreateTableResponse response = glueNamespace.createTable(request, createTestArrowData()); - assertNotNull(response); - assertNotNull(response.getLocation()); - assertTrue(response.getLocation().contains("tbl")); - assertEquals(Long.valueOf(1), response.getVersion()); - - // Verify Lance dataset was created (check for _versions directory) - File tableDir = new File(location); - assertTrue(tableDir.exists()); - assertTrue(tableDir.isDirectory()); - - File versionsDir = new File(location, "_versions"); - assertTrue(versionsDir.exists()); - assertTrue(versionsDir.isDirectory()); - - // Verify dataset can be loaded and has expected schema - try (Dataset dataset = Dataset.open(response.getLocation(), allocator)) { - assertNotNull(dataset); - assertNotNull(dataset.getSchema()); - assertEquals(2, dataset.getSchema().getFields().size()); - assertEquals("id", dataset.getSchema().getFields().get(0).getName()); - assertEquals("name", dataset.getSchema().getFields().get(1).getName()); - } catch (Exception e) { - throw new RuntimeException("Failed to verify created dataset", e); - } - } - - @Test - public void testCreateTableDerivesLocationFromNamespaceUri() throws Exception { - org.lance.namespace.model.CreateTableRequest req = - new org.lance.namespace.model.CreateTableRequest() - .id(ImmutableList.of("ns1", "tbl")); - - Database db = - Database.builder() - .name("ns1") - .locationUri(tempDir.resolve("ns1").toUri().toString()) - .build(); - - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenReturn(GetDatabaseResponse.builder().database(db).build()); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - org.lance.namespace.model.CreateTableResponse resp = - glueNamespace.createTable(req, createTestArrowData()); - - String expectedPrefix = tempDir.resolve("ns1").resolve("tbl").toString(); - assertTrue(resp.getLocation().contains(expectedPrefix)); - - File dir = new File(new URI(resp.getLocation())); - assertTrue(dir.exists(), "Derived table directory must exist"); - assertTrue(new File(dir, "_versions").isDirectory()); - } - - @Test - public void testCreateTableDerivesLocationFromDefaultRootWhenNoNamespaceUri() { - // Initialize with a custom root directory using tempDir - GlueNamespaceConfig config = - new GlueNamespaceConfig(ImmutableMap.of("root", tempDir.toString())); - glueNamespace.initialize(config, glue, allocator); - - org.lance.namespace.model.CreateTableRequest req = - new org.lance.namespace.model.CreateTableRequest() - .id(ImmutableList.of("ns1", "tbl")); - - Database db = Database.builder().name("ns1").build(); - - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenReturn(GetDatabaseResponse.builder().database(db).build()); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - // Now the implementation uses the configured root when namespace URI is missing - org.lance.namespace.model.CreateTableResponse resp = - glueNamespace.createTable(req, createTestArrowData()); - - // The location should be derived from the configured root - assertNotNull(resp.getLocation()); - String expectedLocationPattern = String.format("%s/ns1/tbl.lance", tempDir.toString()); - assertEquals(expectedLocationPattern, resp.getLocation()); - - // Verify the dataset was created - Path tableDir = tempDir.resolve("ns1").resolve("tbl.lance"); - assertTrue(Files.exists(tableDir)); - assertTrue(Files.exists(tableDir.resolve("_versions"))); - } - - @Test - public void testCreateTableConflictCleansUpDataset() { - String namespace = "ns"; - String tbl = "tbl"; - Path loc = tempDir.resolve(namespace).resolve(tbl); - - org.lance.namespace.model.CreateTableRequest req = - new org.lance.namespace.model.CreateTableRequest() - .id(ImmutableList.of(namespace, tbl)) - .location(loc.toString()); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenThrow(AlreadyExistsException.builder().message("Table already exists").build()); - - assertThrows( - LanceNamespaceException.class, () -> glueNamespace.createTable(req, createTestArrowData())); - assertFalse(Files.exists(loc), "Dataset should be removed on exception"); - } - - @Test - public void testCreateTableMissingSchema() { - org.lance.namespace.model.CreateTableRequest req = - new org.lance.namespace.model.CreateTableRequest() - .id(ImmutableList.of("ns", "tbl")) - .location(tempDir.toString()); - - LanceNamespaceException ex = - assertThrows( - LanceNamespaceException.class, () -> glueNamespace.createTable(req, new byte[0])); - assertTrue(ex.getMessage().contains("Arrow IPC")); - } - - @Test - public void testDropTableExplicitLocationOnDisk() { - // First create table - Path location = tempDir.resolve("ns1/tbl"); - List tableId = ImmutableList.of("ns1", "tbl"); - org.lance.namespace.model.CreateTableRequest request = - new org.lance.namespace.model.CreateTableRequest() - .id(tableId) - .location(location.toString()); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - glueNamespace.createTable(request, createTestArrowData()); - - // Verify it exists - File tableDir = new File(location.toString()); - assertTrue(tableDir.exists()); - File versionsDir = new File(tableDir, "_versions"); - assertTrue(versionsDir.exists()); - - // Drop the table - Table tbl = - Table.builder() - .databaseName(tableId.get(0)) - .name(tableId.get(1)) - .storageDescriptor(StorageDescriptor.builder().location(location.toString()).build()) - .parameters(ImmutableMap.of(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE)) - .build(); - when(glue.getTable(any(GetTableRequest.class))) - .thenReturn(GetTableResponse.builder().table(tbl).build()); - - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(tableId); - DropTableResponse response = glueNamespace.dropTable(dropRequest); - - assertNotNull(response); - assertFalse(tableDir.exists()); - } - - @Test - public void testDropTableTableNotFound() { - when(glue.getTable(any(GetTableRequest.class))) - .thenThrow(EntityNotFoundException.builder().message("Entity Not found").build()); - DropTableRequest req = new DropTableRequest().id(ImmutableList.of("ns1", "tbl")); - LanceNamespaceException e = - assertThrows(LanceNamespaceException.class, () -> glueNamespace.dropTable(req)); - - assertTrue(e.getMessage().contains("Glue table not found: ns1.tbl")); - } - - private JsonArrowSchema createTestSchema() { - // Create a simple schema with id (int32) and name (string) fields - JsonArrowDataType intType = new JsonArrowDataType(); - intType.setType("int32"); - - JsonArrowDataType stringType = new JsonArrowDataType(); - stringType.setType("utf8"); - - JsonArrowField idField = new JsonArrowField(); - idField.setName("id"); - idField.setType(intType); - idField.setNullable(false); - - JsonArrowField nameField = new JsonArrowField(); - nameField.setName("name"); - nameField.setType(stringType); - nameField.setNullable(true); - - List fields = new ArrayList<>(); - fields.add(idField); - fields.add(nameField); - - JsonArrowSchema schema = new JsonArrowSchema(); - schema.setFields(fields); - return schema; - } - - private byte[] createTestArrowData() { - // Create a proper Arrow IPC stream with test schema - try { - return org.lance.namespace.util.ArrowIpcUtil.createEmptyArrowIpcStream( - createTestSchema()); - } catch (Exception e) { - throw new RuntimeException("Failed to create test Arrow data", e); - } - } } diff --git a/java/lance-namespace-hive2/pom.xml b/java/lance-namespace-hive2/pom.xml index f21cf78..52585f1 100644 --- a/java/lance-namespace-hive2/pom.xml +++ b/java/lance-namespace-hive2/pom.xml @@ -22,6 +22,10 @@ org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client @@ -159,6 +163,12 @@ 4.1.19 test + + org.lance + lance-namespace-impls-core + ${project.version} + test + org.junit.jupiter junit-jupiter diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ClientPoolImpl.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ClientPoolImpl.java new file mode 100644 index 0000000..e4fcd8c --- /dev/null +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ClientPoolImpl.java @@ -0,0 +1,116 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive2; + +import java.io.Closeable; +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * A simple connection pool implementation for reusing clients. Adapted from Apache Iceberg. + * + * @param the client type + * @param the exception type thrown by client operations + */ +public abstract class ClientPoolImpl implements Closeable { + + private final int poolSize; + private final Deque clients; + private final Class reconnectExc; + private final boolean retryByDefault; + private volatile int currentSize; + private boolean closed; + + protected ClientPoolImpl(int poolSize, Class reconnectExc, boolean retryByDefault) { + this.poolSize = poolSize; + this.clients = new ArrayDeque<>(); + this.reconnectExc = reconnectExc; + this.retryByDefault = retryByDefault; + this.currentSize = 0; + this.closed = false; + } + + public interface Action { + R run(C client) throws E; + } + + public R run(Action action) throws E, InterruptedException { + return run(action, retryByDefault); + } + + public R run(Action action, boolean retry) throws E, InterruptedException { + C client = get(); + try { + return action.run(client); + } catch (Exception exc) { + if (retry && isConnectionException(exc)) { + try { + client = reconnect(client); + } catch (Exception reconnectExc) { + release(client); + throw (E) exc; + } + return action.run(client); + } + throw (E) exc; + } finally { + release(client); + } + } + + protected abstract C newClient(); + + protected abstract C reconnect(C client); + + protected abstract void close(C client); + + protected boolean isConnectionException(Exception exc) { + return reconnectExc.isInstance(exc); + } + + private synchronized C get() throws InterruptedException { + if (closed) { + throw new IllegalStateException("Cannot get a client from a closed pool"); + } + + while (clients.isEmpty() && currentSize >= poolSize) { + wait(); + } + + if (!clients.isEmpty()) { + return clients.removeFirst(); + } + + currentSize++; + return newClient(); + } + + private synchronized void release(C client) { + if (closed) { + close(client); + } else { + clients.addFirst(client); + notify(); + } + } + + @Override + public synchronized void close() { + this.closed = true; + while (!clients.isEmpty()) { + close(clients.removeFirst()); + } + notifyAll(); + } +} diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/CommonUtil.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/CommonUtil.java new file mode 100644 index 0000000..bbfb978 --- /dev/null +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/CommonUtil.java @@ -0,0 +1,36 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive2; + +/** Common utility methods. */ +public class CommonUtil { + + private CommonUtil() {} + + public static String formatCurrentStackTrace() { + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + StringBuilder sb = new StringBuilder(); + for (int i = 2; i < Math.min(stack.length, 10); i++) { + sb.append(stack[i].toString()).append("\n"); + } + return sb.toString(); + } + + public static String makeQualified(String path) { + if (path == null) { + return null; + } + return path.endsWith("/") ? path.substring(0, path.length() - 1) : path; + } +} diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2ClientPool.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2ClientPool.java index 9ee9cb4..eef2bf7 100644 --- a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2ClientPool.java +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2ClientPool.java @@ -13,8 +13,6 @@ */ package org.lance.namespace.hive2; -import org.lance.namespace.util.ClientPoolImpl; - import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.HiveMetaHookLoader; diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java index 1812ac0..cdd99fe 100644 --- a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java @@ -13,38 +13,31 @@ */ package org.lance.namespace.hive2; -import com.lancedb.lance.Dataset; -import com.lancedb.lance.WriteParams; -import org.lance.namespace.Configurable; +import org.lance.Dataset; +import org.lance.WriteParams; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.ObjectIdentifier; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.ServiceUnavailableException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; -import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; import org.lance.namespace.model.NamespaceExistsRequest; import org.lance.namespace.model.TableExistsRequest; -import org.lance.namespace.util.ArrowIpcUtil; -import org.lance.namespace.util.CommonUtil; -import org.lance.namespace.util.JsonArrowSchemaConverter; -import org.lance.namespace.util.PageUtil; -import org.lance.namespace.util.ValidationUtil; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -60,7 +53,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -73,7 +65,7 @@ import static org.lance.namespace.hive2.Hive2ErrorType.TableAlreadyExists; import static org.lance.namespace.hive2.Hive2ErrorType.TableNotFound; -public class Hive2Namespace implements LanceNamespace, Configurable { +public class Hive2Namespace implements LanceNamespace { private static final Logger LOG = LoggerFactory.getLogger(Hive2Namespace.class); private Hive2ClientPool clientPool; @@ -83,6 +75,16 @@ public class Hive2Namespace implements LanceNamespace, Configurable configProperties, BufferAllocator allocator) { this.allocator = allocator; @@ -125,7 +127,7 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { @Override public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { ObjectIdentifier id = ObjectIdentifier.of(request.getId()); - CreateNamespaceRequest.ModeEnum mode = request.getMode(); + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "create"; Map properties = request.getProperties(); ValidationUtil.checkArgument( @@ -149,11 +151,10 @@ public void namespaceExists(NamespaceExistsRequest request) { Database database = Hive2Util.getDatabaseOrNull(clientPool, db); if (database == null) { - throw LanceNamespaceException.notFound( + throw new NamespaceNotFoundException( String.format("Namespace does not exist: %s", id.stringStyleId()), HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + id.stringStyleId()); } } @@ -168,11 +169,10 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ Database database = Hive2Util.getDatabaseOrNull(clientPool, db); if (database == null) { - throw LanceNamespaceException.notFound( + throw new NamespaceNotFoundException( String.format("Namespace does not exist: %s", id.stringStyleId()), HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + id.stringStyleId()); } DescribeNamespaceResponse response = new DescribeNamespaceResponse(); @@ -202,20 +202,12 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ObjectIdentifier id = ObjectIdentifier.of(request.getId()); - DropNamespaceRequest.ModeEnum mode = request.getMode(); - DropNamespaceRequest.BehaviorEnum behavior = request.getBehavior(); + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; ValidationUtil.checkArgument( !id.isRoot() && id.levels() <= 1, "Expect a 1-level namespace but get %s", id); - if (mode == null) { - mode = DropNamespaceRequest.ModeEnum.FAIL; - } - if (behavior == null) { - behavior = DropNamespaceRequest.BehaviorEnum.RESTRICT; - } - - Map properties = doDropNamespace(id, mode, behavior); + Map properties = doDropNamespace(id, mode); DropNamespaceResponse response = new DropNamespaceResponse(); response.setProperties(properties); @@ -256,11 +248,10 @@ public void tableExists(TableExistsRequest request) { Optional hmsTable = Hive2Util.getTable(clientPool, db, table); if (!hmsTable.isPresent()) { - throw LanceNamespaceException.notFound( + throw new TableNotFoundException( String.format("Table does not exist: %s", tableId.stringStyleId()), TableNotFound.getType(), - tableId.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + tableId.stringStyleId()); } Hive2Util.validateLanceTable(hmsTable.get()); @@ -276,11 +267,10 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { Optional location = doDescribeTable(tableId); if (!location.isPresent()) { - throw LanceNamespaceException.notFound( + throw new TableNotFoundException( String.format("Table does not exist: %s", tableId.stringStyleId()), TableNotFound.getType(), - tableId.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + tableId.stringStyleId()); } DescribeTableResponse response = new DescribeTableResponse(); @@ -289,45 +279,7 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { return response; } - @Override - public CreateTableResponse createTable(CreateTableRequest request, byte[] requestData) { - // Validate that requestData is a valid Arrow IPC stream - ValidationUtil.checkNotNull( - requestData, "Request data (Arrow IPC stream) is required for createTable"); - ValidationUtil.checkArgument( - requestData.length > 0, "Request data (Arrow IPC stream) cannot be empty"); - - ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); - - // Extract schema from Arrow IPC stream - JsonArrowSchema jsonSchema; - try { - jsonSchema = ArrowIpcUtil.extractSchemaFromIpc(requestData); - } catch (IOException e) { - throw LanceNamespaceException.badRequest( - "Invalid Arrow IPC stream: " + e.getMessage(), - "INVALID_ARROW_IPC", - tableId.stringStyleId(), - "Failed to extract schema from Arrow IPC stream"); - } - Schema schema = JsonArrowSchemaConverter.convertToArrowSchema(jsonSchema); - - ValidationUtil.checkArgument( - tableId.levels() == 2, "Expect 2-level table identifier but get %s", tableId); - - String location = request.getLocation(); - if (location == null || location.isEmpty()) { - location = getDefaultTableLocation(tableId.levelAtListPos(0), tableId.levelAtListPos(1)); - } - - doCreateTable(tableId, schema, location, request.getProperties(), requestData); - - CreateTableResponse response = new CreateTableResponse(); - response.setLocation(location); - response.setVersion(1L); - response.setStorageOptions(config.getStorageOptions()); - return response; - } + // Removed: createTable(CreateTableRequest, byte[]) - using default implementation from interface @Override public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { @@ -342,7 +294,7 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request } // Create table in metastore without data (pass null for requestData) - doCreateTable(tableId, null, location, request.getProperties(), null); + doCreateTable(tableId, null, location, null, null); CreateEmptyTableResponse response = new CreateEmptyTableResponse(); response.setLocation(location); @@ -350,23 +302,8 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request return response; } - @Override - public DropTableResponse dropTable(DropTableRequest request) { - ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); - - ValidationUtil.checkArgument( - tableId.levels() == 2, "Expect 2-level table identifier but get %s", tableId); + // Removed: dropTable(DropTableRequest) - using default implementation from interface - String location = doDropTable(tableId); - // TODO: remove data - - DropTableResponse response = new DropTableResponse(); - response.setLocation(location); - response.setId(request.getId()); - return response; - } - - @Override public void setConf(Configuration conf) { this.hadoopConf = conf; } @@ -383,16 +320,13 @@ protected List doListNamespaces(ObjectIdentifier parent) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to list namespaces: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to list namespaces: " + errorMessage, HiveMetaStoreError.getType(), ""); } } protected void doCreateNamespace( - ObjectIdentifier id, CreateNamespaceRequest.ModeEnum mode, Map properties) { + ObjectIdentifier id, String mode, Map properties) { try { String db = id.levelAtListPos(0).toLowerCase(); @@ -402,34 +336,26 @@ protected void doCreateNamespace( Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to create namespace: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to create namespace: " + errorMessage, HiveMetaStoreError.getType(), ""); } } - private void createDatabase( - String dbName, CreateNamespaceRequest.ModeEnum mode, Map properties) + private void createDatabase(String dbName, String mode, Map properties) throws TException, InterruptedException { Database oldDb = Hive2Util.getDatabaseOrNull(clientPool, dbName); if (oldDb != null) { - switch (mode) { - case CREATE: - throw LanceNamespaceException.conflict( - String.format("Database %s already exist", dbName), - DatabaseAlreadyExist.getType(), - "", - CommonUtil.formatCurrentStackTrace()); - case EXIST_OK: - return; - case OVERWRITE: - clientPool.run( - client -> { - client.dropDatabase(dbName, false, true, false); - return null; - }); + if ("create".equals(mode)) { + throw new NamespaceAlreadyExistsException( + String.format("Database %s already exist", dbName), DatabaseAlreadyExist.getType(), ""); + } else if ("exist_ok".equals(mode) || "existok".equals(mode)) { + return; + } else if ("overwrite".equals(mode)) { + clientPool.run( + client -> { + client.dropDatabase(dbName, false, true, false); + return null; + }); } } @@ -491,11 +417,10 @@ protected void doCreateTable( try { Optional
existing = Hive2Util.getTable(clientPool, db, tableName); if (existing.isPresent()) { - throw LanceNamespaceException.conflict( + throw new TableAlreadyExistsException( String.format("Table %s.%s already exists", db, tableName), TableAlreadyExists.getType(), - String.format("%s.%s", db, tableName), - CommonUtil.formatCurrentStackTrace()); + String.format("%s.%s", db, tableName)); } Table table = new Table(); @@ -537,11 +462,8 @@ protected void doCreateTable( Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to create table: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to create table: " + errorMessage, HiveMetaStoreError.getType(), ""); } } @@ -550,11 +472,8 @@ protected List doListTables(String db) { // First validate that database exists Database database = Hive2Util.getDatabaseOrNull(clientPool, db); if (database == null) { - throw LanceNamespaceException.notFound( - String.format("Database %s doesn't exist", db), - HiveMetaStoreError.getType(), - db, - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Database %s doesn't exist", db), HiveMetaStoreError.getType(), db); } List allTables = clientPool.run(client -> client.getAllTables(db)); @@ -581,11 +500,8 @@ protected List doListTables(String db) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to list tables: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to list tables: " + errorMessage, HiveMetaStoreError.getType(), ""); } } @@ -596,11 +512,10 @@ protected String doDropTable(ObjectIdentifier id) { try { Optional
hmsTable = Hive2Util.getTable(clientPool, db, tableName); if (!hmsTable.isPresent()) { - throw LanceNamespaceException.notFound( + throw new TableNotFoundException( String.format("Table %s.%s does not exist", db, tableName), TableNotFound.getType(), - String.format("%s.%s", db, tableName), - CommonUtil.formatCurrentStackTrace()); + String.format("%s.%s", db, tableName)); } Hive2Util.validateLanceTable(hmsTable.get()); @@ -618,64 +533,33 @@ protected String doDropTable(ObjectIdentifier id) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to drop table: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to drop table: " + errorMessage, HiveMetaStoreError.getType(), ""); } } - protected Map doDropNamespace( - ObjectIdentifier id, - DropNamespaceRequest.ModeEnum mode, - DropNamespaceRequest.BehaviorEnum behavior) { + protected Map doDropNamespace(ObjectIdentifier id, String mode) { String db = id.levelAtListPos(0).toLowerCase(); try { Database database = Hive2Util.getDatabaseOrNull(clientPool, db); if (database == null) { - if (mode == DropNamespaceRequest.ModeEnum.SKIP) { - // Return empty properties for SKIP mode when namespace doesn't exist + if ("skip".equals(mode)) { return new HashMap<>(); } else { - throw LanceNamespaceException.notFound( - String.format("Database %s doesn't exist", db), - HiveMetaStoreError.getType(), - db, - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Database %s doesn't exist", db), HiveMetaStoreError.getType(), db); } } - // Check if database contains tables + // Check if database contains tables (RESTRICT mode only) List tables = doListTables(db); if (!tables.isEmpty()) { - if (behavior == DropNamespaceRequest.BehaviorEnum.RESTRICT) { - throw LanceNamespaceException.badRequest( - String.format( - "Database %s is not empty. Contains %d tables: %s", db, tables.size(), tables), - HiveMetaStoreError.getType(), - db, - CommonUtil.formatCurrentStackTrace()); - } else if (behavior == DropNamespaceRequest.BehaviorEnum.CASCADE) { - // Drop all tables first - for (String tableName : tables) { - try { - ObjectIdentifier tableId = ObjectIdentifier.of(Lists.newArrayList(db, tableName)); - doDropTable(tableId); - LOG.info("Dropped table {}.{} during CASCADE operation", db, tableName); - } catch (Exception e) { - LOG.warn("Failed to drop table {}.{}: {}", db, tableName, e.getMessage()); - throw LanceNamespaceException.serviceUnavailable( - String.format( - "Failed to drop table %s.%s during CASCADE operation: %s", - db, tableName, e.getMessage()), - HiveMetaStoreError.getType(), - String.format("%s.%s", db, tableName), - CommonUtil.formatCurrentStackTrace()); - } - } - } + throw new InvalidInputException( + String.format( + "Database %s is not empty. Contains %d tables: %s", db, tables.size(), tables), + HiveMetaStoreError.getType(), + db); } // Collect database properties before dropping @@ -710,11 +594,8 @@ protected Map doDropNamespace( Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to drop namespace: " + errorMessage, - HiveMetaStoreError.getType(), - db, - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException( + "Failed to drop namespace: " + errorMessage, HiveMetaStoreError.getType(), db); } } diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2NamespaceConfig.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2NamespaceConfig.java index 9237c92..28a5e41 100644 --- a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2NamespaceConfig.java +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2NamespaceConfig.java @@ -13,9 +13,7 @@ */ package org.lance.namespace.hive2; -import org.lance.namespace.util.OpenDalUtil; -import org.lance.namespace.util.PropertyUtil; - +import java.util.HashMap; import java.util.Map; public class Hive2NamespaceConfig { @@ -41,12 +39,27 @@ public class Hive2NamespaceConfig { private final String root; public Hive2NamespaceConfig(Map properties) { + // Inline PropertyUtil.propertyAsInt + String clientPoolSizeStr = properties.get(CLIENT_POOL_SIZE); this.clientPoolSize = - PropertyUtil.propertyAsInt(properties, CLIENT_POOL_SIZE, CLIENT_POOL_SIZE_DEFAULT); - this.storageOptions = PropertyUtil.propertiesWithPrefix(properties, STORAGE_OPTIONS_PREFIX); + clientPoolSizeStr != null ? Integer.parseInt(clientPoolSizeStr) : CLIENT_POOL_SIZE_DEFAULT; + + // Inline PropertyUtil.propertiesWithPrefix + Map filteredStorageOptions = new HashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + if (entry.getKey().startsWith(STORAGE_OPTIONS_PREFIX)) { + filteredStorageOptions.put( + entry.getKey().substring(STORAGE_OPTIONS_PREFIX.length()), entry.getValue()); + } + } + this.storageOptions = filteredStorageOptions; + + // Inline PropertyUtil.propertyAsString and OpenDalUtil.stripTrailingSlash + String rootValue = properties.getOrDefault(ROOT, ROOT_DEFAULT); this.root = - OpenDalUtil.stripTrailingSlash( - PropertyUtil.propertyAsString(properties, ROOT, ROOT_DEFAULT)); + rootValue != null && rootValue.endsWith("/") + ? rootValue.substring(0, rootValue.length() - 1) + : rootValue; } public int getClientPoolSize() { diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Util.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Util.java index 4f26739..23c5374 100644 --- a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Util.java +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Util.java @@ -13,8 +13,8 @@ */ package org.lance.namespace.hive2; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.util.CommonUtil; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.ServiceUnavailableException; import com.google.common.collect.Maps; import org.apache.hadoop.hive.metastore.api.Database; @@ -44,8 +44,7 @@ public static Database getDatabaseOrNull(Hive2ClientPool clientPool, String db) if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage(), HiveMetaStoreError.getType(), ""); } } @@ -103,20 +102,18 @@ public static Optional
getTable(Hive2ClientPool clientPool, String db, St if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage(), HiveMetaStoreError.getType(), ""); } } public static void validateLanceTable(Table table) { Map params = table.getParameters(); if (params == null || !"lance".equalsIgnoreCase(params.get("table_type"))) { - throw LanceNamespaceException.badRequest( + throw new InvalidInputException( String.format( "Table %s.%s is not a Lance table", table.getDbName(), table.getTableName()), InvalidLanceTable.getType(), - String.format("%s.%s", table.getDbName(), table.getTableName()), - CommonUtil.formatCurrentStackTrace()); + String.format("%s.%s", table.getDbName(), table.getTableName())); } } diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ObjectIdentifier.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ObjectIdentifier.java new file mode 100644 index 0000000..af3f0de --- /dev/null +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ObjectIdentifier.java @@ -0,0 +1,55 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive2; + +import java.util.Collections; +import java.util.List; + +/** Represents a hierarchical identifier for namespaces and tables. */ +public class ObjectIdentifier { + private final List levels; + + private ObjectIdentifier(List levels) { + this.levels = levels != null ? levels : Collections.emptyList(); + } + + public static ObjectIdentifier of(List levels) { + return new ObjectIdentifier(levels); + } + + public boolean isRoot() { + return levels.isEmpty(); + } + + public int levels() { + return levels.size(); + } + + public String levelAtListPos(int pos) { + if (pos < 0 || pos >= levels.size()) { + throw new IndexOutOfBoundsException( + "Position " + pos + " is out of bounds for size " + levels.size()); + } + return levels.get(pos); + } + + public String stringStyleId() { + return String.join(".", levels); + } + + @Override + public String toString() { + return stringStyleId(); + } +} diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/PageUtil.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/PageUtil.java new file mode 100644 index 0000000..3acf941 --- /dev/null +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/PageUtil.java @@ -0,0 +1,70 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive2; + +import java.util.List; + +/** Utility methods for pagination. */ +public class PageUtil { + + private static final int DEFAULT_PAGE_SIZE = 100; + + private PageUtil() {} + + public static int normalizePageSize(Integer pageSize) { + if (pageSize == null || pageSize <= 0) { + return DEFAULT_PAGE_SIZE; + } + return pageSize; + } + + public static Page splitPage(List items, String pageToken, int pageSize) { + int startIndex = 0; + if (pageToken != null && !pageToken.isEmpty()) { + try { + startIndex = Integer.parseInt(pageToken); + } catch (NumberFormatException e) { + startIndex = 0; + } + } + + if (startIndex >= items.size()) { + return new Page(java.util.Collections.emptyList(), null); + } + + int endIndex = Math.min(startIndex + pageSize, items.size()); + List pageItems = items.subList(startIndex, endIndex); + + String nextPageToken = endIndex < items.size() ? String.valueOf(endIndex) : null; + return new Page(pageItems, nextPageToken); + } + + public static class Page { + private final List items; + private final String nextPageToken; + + public Page(List items, String nextPageToken) { + this.items = items; + this.nextPageToken = nextPageToken; + } + + public List items() { + return items; + } + + public String nextPageToken() { + return nextPageToken; + } + } +} diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ValidationUtil.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ValidationUtil.java new file mode 100644 index 0000000..3652187 --- /dev/null +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/ValidationUtil.java @@ -0,0 +1,35 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive2; + +import org.lance.namespace.errors.InvalidInputException; + +/** Utility methods for validation. */ +public class ValidationUtil { + + private ValidationUtil() {} + + public static void checkArgument(boolean expression, String message, Object... args) { + if (!expression) { + throw new InvalidInputException(String.format(message, args)); + } + } + + public static String checkNotNullOrEmptyString(String value, String message) { + if (value == null || value.isEmpty()) { + throw new InvalidInputException(message); + } + return value; + } +} diff --git a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2Namespace.java b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2Namespace.java index c6073e8..27bbb82 100644 --- a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2Namespace.java +++ b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2Namespace.java @@ -14,20 +14,13 @@ package org.lance.namespace.hive2; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.LanceNamespaces; -import org.lance.namespace.TestHelper; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; -import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; import org.lance.namespace.model.NamespaceExistsRequest; @@ -41,7 +34,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.io.File; @@ -74,7 +66,10 @@ public static void setup() throws IOException { tmpDirBase = file.getAbsolutePath(); HiveConf hiveConf = metastore.hiveConf(); - namespace = LanceNamespaces.connect("hive2", Maps.newHashMap(), hiveConf, allocator); + Hive2Namespace hive2Namespace = new Hive2Namespace(); + hive2Namespace.setHadoopConf(hiveConf); + hive2Namespace.initialize(Maps.newHashMap(), allocator); + namespace = hive2Namespace; } @AfterAll @@ -97,123 +92,12 @@ public void cleanup() throws Exception { metastore.reset(); } - @Disabled("Need to figure out the proper interface") - @Test - public void testCreateTable() throws IOException { - // Setup: Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Test: Create table with valid parameters - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db", "test_table")); - request.setLocation(tmpDirBase + "/test_db/test_table.lance"); - - Map properties = Maps.newHashMap(); - properties.put("custom_prop", "custom_value"); - request.setProperties(properties); - - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = namespace.createTable(request, testData); - - assertEquals(request.getLocation(), response.getLocation()); - assertEquals(1L, response.getVersion()); - } - - @Test - public void testCreateTableAlreadyExists() throws IOException { - // Setup: Create database and table - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db", "test_table")); - request.setLocation(tmpDirBase + "/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(request, testData); - - // Test: Create table that already exists - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.createTable(request, testData)); - assertTrue(error.getMessage().contains("Table test_db.test_table already exists")); - } - - @Test - public void testCreateTableManagedByImpl() throws IOException { - // Setup: Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Test: Create table with managed_by=impl (not supported) - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db", "impl_table")); - request.setLocation(tmpDirBase + "/test_db/impl_table.lance"); - - Map properties = Maps.newHashMap(); - properties.put("managed_by", "impl"); - request.setProperties(properties); - - byte[] testData = TestHelper.createTestArrowData(allocator); - Exception error = - assertThrows( - UnsupportedOperationException.class, () -> namespace.createTable(request, testData)); - assertTrue(error.getMessage().contains("managed_by=impl is not supported yet")); - } - - @Test - public void testCreateTableWithoutData() throws IOException { - // Setup: Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Test: Create table without data - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db", "no_data_table")); - request.setLocation(tmpDirBase + "/test_db/no_data_table.lance"); - - byte[] emptyData = TestHelper.createEmptyArrowData(allocator); - CreateTableResponse response = namespace.createTable(request, emptyData); - assertEquals(request.getLocation(), response.getLocation()); - } - - @Test - public void testDescribeTable() throws IOException { - // Setup: Create database and table - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Describe existing Lance table - DescribeTableRequest request = new DescribeTableRequest(); - request.setId(Lists.list("test_db", "test_table")); - - DescribeTableResponse response = namespace.describeTable(request); - assertEquals("file:" + tmpDirBase + "/test_db/test_table.lance", response.getLocation()); - } - @Test public void testDescribeNonExistentTable() { // Setup: Create database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); // Test: Describe non-existent table @@ -224,133 +108,12 @@ public void testDescribeNonExistentTable() { assertTrue(error.getMessage().contains("Table does not exist")); } - @Test - public void testDropTable() throws IOException { - // Setup: Create database and table - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Drop existing table - DropTableRequest request = new DropTableRequest(); - request.setId(Lists.list("test_db", "test_table")); - - DropTableResponse response = namespace.dropTable(request); - assertEquals("file:" + tmpDirBase + "/test_db/test_table.lance", response.getLocation()); - assertEquals(request.getId(), response.getId()); - - // Verify table is dropped by trying to describe it - DescribeTableRequest descRequest = new DescribeTableRequest(); - descRequest.setId(request.getId()); - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.describeTable(descRequest)); - assertTrue(error.getMessage().contains("Table does not exist")); - } - - @Test - public void testDropNonExistentTable() { - // Setup: Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Test: Drop non-existent table - DropTableRequest request = new DropTableRequest(); - request.setId(Lists.list("test_db", "non_existent")); - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.dropTable(request)); - assertTrue(error.getMessage().contains("Table test_db.non_existent does not exist")); - } - - @Test - public void testCreateTableWithDefaultLocationFromRoot() throws IOException { - // With our enhancement, databases created without explicit location - // will use the root config location instead of Hive warehouse - - // Setup: Create namespace with custom root configuration - Map properties = Maps.newHashMap(); - properties.put("root", tmpDirBase); - - HiveConf hiveConf = metastore.hiveConf(); - LanceNamespace customNamespace = - LanceNamespaces.connect("hive2", properties, hiveConf, allocator); - - // Setup: Create database (will use root location) - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - customNamespace.createNamespace(nsRequest); - - // Test: Create table without specifying location - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db", "test_table")); - // Don't set location - it will be derived from database location - - // Create test Arrow IPC data - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = customNamespace.createTable(request, testData); - - // Verify: Location should be derived from root-based database location - // Hive adds file: prefix to locations - String expectedLocation = "file:" + tmpDirBase + "/test_db/test_table.lance"; - assertEquals(expectedLocation, response.getLocation()); - assertEquals(1L, response.getVersion()); - } - - @Test - public void testCreateTableWithDefaultLocationFromDatabaseLocation() throws IOException { - // Setup: Create namespace with custom root configuration - Map properties = Maps.newHashMap(); - properties.put("root", tmpDirBase); - - HiveConf hiveConf = metastore.hiveConf(); - LanceNamespace customNamespace = - LanceNamespaces.connect("hive2", properties, hiveConf, allocator); - - // Setup: Create database with specific location - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db_with_location")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - - // Set database location - this should take precedence over root config - String databaseLocation = tmpDirBase + "/custom_db_location"; - Map dbProperties = Maps.newHashMap(); - dbProperties.put("database.location-uri", databaseLocation); - nsRequest.setProperties(dbProperties); - - customNamespace.createNamespace(nsRequest); - - // Test: Create table without specifying location (should derive from database location) - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_db_with_location", "test_table")); - // Don't set location - it should be derived from database location - - // Create test Arrow IPC data - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = customNamespace.createTable(request, testData); - - // Verify: Location should be derived as {database_location}/{table}.lance - // Database locations in Hive typically have file: prefix - String expectedLocation = "file:" + databaseLocation + "/test_table.lance"; - assertEquals(expectedLocation, response.getLocation()); - assertEquals(1L, response.getVersion()); - } - @Test public void testDescribeNamespace() { // Setup: Create database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); Map properties = Maps.newHashMap(); properties.put("database.description", "Test database description"); @@ -388,7 +151,7 @@ public void testNamespaceExists() { // Setup: Create database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); // Test: Check existing namespace @@ -410,35 +173,12 @@ public void testNamespaceExistsNonExistent() { assertTrue(error.getMessage().contains("Namespace does not exist")); } - @Test - public void testTableExists() throws IOException { - // Setup: Create database and table - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Check existing table - TableExistsRequest request = new TableExistsRequest(); - request.setId(Lists.list("test_db", "test_table")); - - // Should not throw exception for existing Lance table - namespace.tableExists(request); - } - @Test public void testTableExistsNonExistent() { // Setup: Create database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); // Test: Check non-existent table @@ -450,46 +190,12 @@ public void testTableExistsNonExistent() { assertTrue(error.getMessage().contains("Table does not exist")); } - @Test - public void testListTables() throws IOException { - // Setup: Create database and multiple tables - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Create first table - CreateTableRequest createRequest1 = new CreateTableRequest(); - createRequest1.setId(Lists.list("test_db", "table1")); - createRequest1.setLocation(tmpDirBase + "/test_db/table1.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest1, testData); - - // Create second table - CreateTableRequest createRequest2 = new CreateTableRequest(); - createRequest2.setId(Lists.list("test_db", "table2")); - createRequest2.setLocation(tmpDirBase + "/test_db/table2.lance"); - - namespace.createTable(createRequest2, testData); - - // Test: List tables - ListTablesRequest request = new ListTablesRequest(); - request.setId(Lists.list("test_db")); - - ListTablesResponse response = namespace.listTables(request); - - assertEquals(2, response.getTables().size()); - assertTrue(response.getTables().contains("table1")); - assertTrue(response.getTables().contains("table2")); - } - @Test public void testListTablesEmpty() { // Setup: Create empty database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("empty_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); // Test: List tables in empty database @@ -501,47 +207,6 @@ public void testListTablesEmpty() { assertEquals(0, response.getTables().size()); } - @Test - public void testListTablesWithPagination() throws IOException { - // Setup: Create database and multiple tables - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Create multiple tables - for (int i = 1; i <= 5; i++) { - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_db", "table" + i)); - createRequest.setLocation(tmpDirBase + "/test_db/table" + i + ".lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - } - - // Test: List tables with pagination (limit 3) - ListTablesRequest request = new ListTablesRequest(); - request.setId(Lists.list("test_db")); - request.setLimit(3); - - ListTablesResponse response = namespace.listTables(request); - - assertEquals(3, response.getTables().size()); - // Should have a page token for remaining results - assertTrue(response.getPageToken() != null && !response.getPageToken().isEmpty()); - - // Get remaining tables - ListTablesRequest nextRequest = new ListTablesRequest(); - nextRequest.setId(Lists.list("test_db")); - nextRequest.setPageToken(response.getPageToken()); - - ListTablesResponse nextResponse = namespace.listTables(nextRequest); - - assertEquals(2, nextResponse.getTables().size()); - // No more pages - assertTrue(nextResponse.getPageToken() == null || nextResponse.getPageToken().isEmpty()); - } - @Test public void testListTablesNonExistentDatabase() { // Test: List tables in non-existent database @@ -558,7 +223,7 @@ public void testDropNamespaceBasic() { // Setup: Create database CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_db_basic")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); Map properties = Maps.newHashMap(); properties.put("database.description", "Test database for dropping"); @@ -592,7 +257,7 @@ public void testDropNamespaceSkipMode() { // Test: Drop non-existent namespace with SKIP mode DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("non_existent_db")); - dropRequest.setMode(DropNamespaceRequest.ModeEnum.SKIP); + dropRequest.setMode("Skip"); DropNamespaceResponse response = namespace.dropNamespace(dropRequest); @@ -605,78 +270,10 @@ public void testDropNamespaceFailMode() { // Test: Drop non-existent namespace with FAIL mode (default) DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("non_existent_db")); - dropRequest.setMode(DropNamespaceRequest.ModeEnum.FAIL); + dropRequest.setMode("Fail"); Exception error = assertThrows(LanceNamespaceException.class, () -> namespace.dropNamespace(dropRequest)); assertTrue(error.getMessage().contains("Database non_existent_db doesn't exist")); } - - @Test - public void testDropNamespaceRestrictWithTables() throws IOException { - // Setup: Create database and table - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db_restrict")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_db_restrict", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_db_restrict/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Try to drop namespace with RESTRICT behavior (should fail) - DropNamespaceRequest dropRequest = new DropNamespaceRequest(); - dropRequest.setId(Lists.list("test_db_restrict")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.RESTRICT); - - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.dropNamespace(dropRequest)); - assertTrue(error.getMessage().contains("Database test_db_restrict is not empty")); - assertTrue(error.getMessage().contains("Contains 1 tables")); - } - - @Test - public void testDropNamespaceCascadeWithTables() throws IOException { - // Setup: Create database and multiple tables - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_db_cascade")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Create first table - CreateTableRequest createRequest1 = new CreateTableRequest(); - createRequest1.setId(Lists.list("test_db_cascade", "table1")); - createRequest1.setLocation(tmpDirBase + "/test_db_cascade/table1.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest1, testData); - - // Create second table - CreateTableRequest createRequest2 = new CreateTableRequest(); - createRequest2.setId(Lists.list("test_db_cascade", "table2")); - createRequest2.setLocation(tmpDirBase + "/test_db_cascade/table2.lance"); - - namespace.createTable(createRequest2, testData); - - // Test: Drop namespace with CASCADE behavior - DropNamespaceRequest dropRequest = new DropNamespaceRequest(); - dropRequest.setId(Lists.list("test_db_cascade")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); - - DropNamespaceResponse response = namespace.dropNamespace(dropRequest); - - // Verify namespace properties were returned - assertTrue(response.getProperties().containsKey("database.location-uri")); - - // Verify namespace was dropped - NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); - existsRequest.setId(Lists.list("test_db_cascade")); - - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.namespaceExists(existsRequest)); - assertTrue(error.getMessage().contains("Namespace does not exist")); - } } diff --git a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java index ca95529..6f1347b 100644 --- a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java +++ b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java @@ -13,7 +13,7 @@ */ package org.lance.namespace.hive2; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; @@ -114,19 +114,13 @@ public void tearDown() { // Clean up test database DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Collections.singletonList(testDatabase)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors } - if (namespace != null) { - try { - namespace.close(); - } catch (Exception e) { - // Ignore - } - } + // Namespace cleanup handled by Hive internals if (allocator != null) { allocator.close(); @@ -163,8 +157,8 @@ public void testDatabaseOperations() { DescribeNamespaceResponse describeResponse = namespace.describeNamespace(describeRequest); assertThat(describeResponse).isNotNull(); - assertThat(describeResponse.getProperties()).containsEntry( - "database.description", "Integration test database"); + assertThat(describeResponse.getProperties()) + .containsEntry("database.description", "Integration test database"); // List databases ListNamespacesRequest listRequest = new ListNamespacesRequest(); @@ -190,7 +184,8 @@ public void testTableOperations() { nsRequest.setId(Collections.singletonList(testDatabase)); namespace.createNamespace(nsRequest); - String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); + String tableName = + "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); // Create empty table (declare table without data) CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); @@ -206,7 +201,6 @@ public void testTableOperations() { DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); assertThat(describeResponse.getLocation()).contains(tableName); - assertThat(describeResponse.getProperties()).containsEntry("table_type", "lance"); // List tables ListTablesRequest listRequest = new ListTablesRequest(); @@ -242,7 +236,7 @@ public void testCascadeDropDatabase() { // Drop database with cascade DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Collections.singletonList(testDatabase)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); // Verify database doesn't exist diff --git a/java/lance-namespace-hive3/pom.xml b/java/lance-namespace-hive3/pom.xml index f16eaa9..54616be 100644 --- a/java/lance-namespace-hive3/pom.xml +++ b/java/lance-namespace-hive3/pom.xml @@ -22,6 +22,10 @@ org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client @@ -73,6 +77,12 @@ 10.14.2.0 test + + org.lance + lance-namespace-impls-core + ${project.version} + test + org.junit.jupiter junit-jupiter diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ClientPoolImpl.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ClientPoolImpl.java new file mode 100644 index 0000000..2a268df --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ClientPoolImpl.java @@ -0,0 +1,116 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +import java.io.Closeable; +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * A simple connection pool implementation for reusing clients. Adapted from Apache Iceberg. + * + * @param the client type + * @param the exception type thrown by client operations + */ +public abstract class ClientPoolImpl implements Closeable { + + private final int poolSize; + private final Deque clients; + private final Class reconnectExc; + private final boolean retryByDefault; + private volatile int currentSize; + private boolean closed; + + protected ClientPoolImpl(int poolSize, Class reconnectExc, boolean retryByDefault) { + this.poolSize = poolSize; + this.clients = new ArrayDeque<>(); + this.reconnectExc = reconnectExc; + this.retryByDefault = retryByDefault; + this.currentSize = 0; + this.closed = false; + } + + public interface Action { + R run(C client) throws E; + } + + public R run(Action action) throws E, InterruptedException { + return run(action, retryByDefault); + } + + public R run(Action action, boolean retry) throws E, InterruptedException { + C client = get(); + try { + return action.run(client); + } catch (Exception exc) { + if (retry && isConnectionException(exc)) { + try { + client = reconnect(client); + } catch (Exception reconnectExc) { + release(client); + throw (E) exc; + } + return action.run(client); + } + throw (E) exc; + } finally { + release(client); + } + } + + protected abstract C newClient(); + + protected abstract C reconnect(C client); + + protected abstract void close(C client); + + protected boolean isConnectionException(Exception exc) { + return reconnectExc.isInstance(exc); + } + + private synchronized C get() throws InterruptedException { + if (closed) { + throw new IllegalStateException("Cannot get a client from a closed pool"); + } + + while (clients.isEmpty() && currentSize >= poolSize) { + wait(); + } + + if (!clients.isEmpty()) { + return clients.removeFirst(); + } + + currentSize++; + return newClient(); + } + + private synchronized void release(C client) { + if (closed) { + close(client); + } else { + clients.addFirst(client); + notify(); + } + } + + @Override + public synchronized void close() { + this.closed = true; + while (!clients.isEmpty()) { + close(clients.removeFirst()); + } + notifyAll(); + } +} diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/CommonUtil.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/CommonUtil.java new file mode 100644 index 0000000..9d4194f --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/CommonUtil.java @@ -0,0 +1,36 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +/** Common utility methods. */ +public class CommonUtil { + + private CommonUtil() {} + + public static String formatCurrentStackTrace() { + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + StringBuilder sb = new StringBuilder(); + for (int i = 2; i < Math.min(stack.length, 10); i++) { + sb.append(stack[i].toString()).append("\n"); + } + return sb.toString(); + } + + public static String makeQualified(String path) { + if (path == null) { + return null; + } + return path.endsWith("/") ? path.substring(0, path.length() - 1) : path; + } +} diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/DynMethods.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/DynMethods.java new file mode 100644 index 0000000..7bf259a --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/DynMethods.java @@ -0,0 +1,491 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Arrays; + +/** Copied from parquet-common */ +public class DynMethods { + + private DynMethods() {} + + /** + * Convenience wrapper class around {@link java.lang.reflect.Method}. + * + *

Allows callers to invoke the wrapped method with all Exceptions wrapped by RuntimeException, + * or with a single Exception catch block. + */ + public static class UnboundMethod { + + private final Method method; + private final String name; + private final int argLength; + + UnboundMethod(Method method, String name) { + this.method = method; + this.name = name; + this.argLength = + (method == null || method.isVarArgs()) ? -1 : method.getParameterTypes().length; + } + + @SuppressWarnings("unchecked") + R invokeChecked(Object target, Object... args) throws Exception { + try { + if (argLength < 0) { + return (R) method.invoke(target, args); + } else { + return (R) method.invoke(target, Arrays.copyOfRange(args, 0, argLength)); + } + + } catch (InvocationTargetException e) { + Throwables.propagateIfInstanceOf(e.getCause(), Exception.class); + Throwables.propagateIfInstanceOf(e.getCause(), RuntimeException.class); + throw Throwables.propagate(e.getCause()); + } + } + + public R invoke(Object target, Object... args) { + try { + return this.invokeChecked(target, args); + } catch (Exception e) { + Throwables.propagateIfInstanceOf(e, RuntimeException.class); + throw Throwables.propagate(e); + } + } + + /** + * Returns this method as a BoundMethod for the given receiver. + * + * @param receiver an Object to receive the method invocation + * @return a {@link BoundMethod} for this method and the receiver + * @throws IllegalStateException if the method is static + * @throws IllegalArgumentException if the receiver's class is incompatible + */ + public BoundMethod bind(Object receiver) { + Preconditions.checkState( + !isStatic(), "Cannot bind static method %s", method.toGenericString()); + Preconditions.checkArgument( + method.getDeclaringClass().isAssignableFrom(receiver.getClass()), + "Cannot bind %s to instance of %s", + method.toGenericString(), + receiver.getClass()); + + return new BoundMethod(this, receiver); + } + + /** Returns whether the method is a static method. */ + public boolean isStatic() { + return Modifier.isStatic(method.getModifiers()); + } + + /** Returns whether the method is a noop. */ + public boolean isNoop() { + return this == NOOP; + } + + /** + * Returns this method as a StaticMethod. + * + * @return a {@link StaticMethod} for this method + * @throws IllegalStateException if the method is not static + */ + public StaticMethod asStatic() { + Preconditions.checkState(isStatic(), "Method is not static"); + return new StaticMethod(this); + } + + @Override + public String toString() { + return "DynMethods.UnboundMethod(name=" + name + " method=" + method.toGenericString() + ")"; + } + + /** Singleton {@link UnboundMethod}, performs no operation and returns null. */ + private static final UnboundMethod NOOP = + new UnboundMethod(null, "NOOP") { + @Override + R invokeChecked(Object target, Object... args) { + return null; + } + + @Override + public BoundMethod bind(Object receiver) { + return new BoundMethod(this, receiver); + } + + @Override + public StaticMethod asStatic() { + return new StaticMethod(this); + } + + @Override + public boolean isStatic() { + return true; + } + + @Override + public String toString() { + return "DynMethods.UnboundMethod(NOOP)"; + } + }; + } + + public static class BoundMethod { + private final UnboundMethod method; + private final Object receiver; + + private BoundMethod(UnboundMethod method, Object receiver) { + this.method = method; + this.receiver = receiver; + } + + public R invokeChecked(Object... args) throws Exception { + return method.invokeChecked(receiver, args); + } + + public R invoke(Object... args) { + return method.invoke(receiver, args); + } + } + + public static class StaticMethod { + private final UnboundMethod method; + + private StaticMethod(UnboundMethod method) { + this.method = method; + } + + public R invokeChecked(Object... args) throws Exception { + return method.invokeChecked(null, args); + } + + public R invoke(Object... args) { + return method.invoke(null, args); + } + } + + /** + * Constructs a new builder for calling methods dynamically. + * + * @param methodName name of the method the builder will locate + * @return a Builder for finding a method + */ + public static Builder builder(String methodName) { + return new Builder(methodName); + } + + public static class Builder { + private final String name; + private ClassLoader loader = Thread.currentThread().getContextClassLoader(); + private UnboundMethod method = null; + + public Builder(String methodName) { + this.name = methodName; + } + + /** + * Set the {@link ClassLoader} used to lookup classes by name. + * + *

If not set, the current thread's ClassLoader is used. + * + * @param newLoader a ClassLoader + * @return this Builder for method chaining + */ + public Builder loader(ClassLoader newLoader) { + this.loader = newLoader; + return this; + } + + /** + * If no implementation has been found, adds a NOOP method. + * + *

Note: calls to impl will not match after this method is called! + * + * @return this Builder for method chaining + */ + public Builder orNoop() { + if (method == null) { + this.method = UnboundMethod.NOOP; + } + return this; + } + + /** + * Checks for an implementation, first finding the given class by name. + * + * @param className name of a class + * @param methodName name of a method (different from constructor) + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder impl(String className, String methodName, Class... argClasses) { + // don't do any work if an implementation has been found + if (method != null) { + return this; + } + + try { + Class targetClass = Class.forName(className, true, loader); + impl(targetClass, methodName, argClasses); + } catch (ClassNotFoundException e) { + // not the right implementation + } + return this; + } + + /** + * Checks for an implementation, first finding the given class by name. + * + *

The name passed to the constructor is the method name used. + * + * @param className name of a class + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder impl(String className, Class... argClasses) { + impl(className, name, argClasses); + return this; + } + + /** + * Checks for a method implementation. + * + * @param targetClass a class instance + * @param methodName name of a method (different from constructor) + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder impl(Class targetClass, String methodName, Class... argClasses) { + // don't do any work if an implementation has been found + if (method != null) { + return this; + } + + try { + this.method = new UnboundMethod(targetClass.getMethod(methodName, argClasses), name); + } catch (NoSuchMethodException e) { + // not the right implementation + } + return this; + } + + /** + * Checks for a method implementation. + * + *

The name passed to the constructor is the method name used. + * + * @param targetClass a class instance + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder impl(Class targetClass, Class... argClasses) { + impl(targetClass, name, argClasses); + return this; + } + + /** + * Checks for an implementation, first finding the given class by name. + * + * @param className name of a class + * @param methodName name of a method (different from constructor) + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder hiddenImpl(String className, String methodName, Class... argClasses) { + // don't do any work if an implementation has been found + if (method != null) { + return this; + } + + try { + Class targetClass = Class.forName(className, true, loader); + hiddenImpl(targetClass, methodName, argClasses); + } catch (ClassNotFoundException e) { + // not the right implementation + } + return this; + } + + /** + * Checks for an implementation, first finding the given class by name. + * + *

The name passed to the constructor is the method name used. + * + * @param className name of a class + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder hiddenImpl(String className, Class... argClasses) { + hiddenImpl(className, name, argClasses); + return this; + } + + /** + * Checks for a method implementation. + * + * @param targetClass a class instance + * @param methodName name of a method (different from constructor) + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder hiddenImpl(Class targetClass, String methodName, Class... argClasses) { + // don't do any work if an implementation has been found + if (method != null) { + return this; + } + + try { + Method hidden = targetClass.getDeclaredMethod(methodName, argClasses); + AccessController.doPrivileged(new MakeAccessible(hidden)); + this.method = new UnboundMethod(hidden, name); + } catch (SecurityException | NoSuchMethodException e) { + // unusable or not the right implementation + } + return this; + } + + /** + * Checks for a method implementation. + * + *

The name passed to the constructor is the method name used. + * + * @param targetClass a class instance + * @param argClasses argument classes for the method + * @return this Builder for method chaining + * @see java.lang.Class#forName(String) + * @see java.lang.Class#getMethod(String, Class[]) + */ + public Builder hiddenImpl(Class targetClass, Class... argClasses) { + hiddenImpl(targetClass, name, argClasses); + return this; + } + + /** + * Returns the first valid implementation as a UnboundMethod or throws a RuntimeError if there + * is none. + * + * @return a {@link UnboundMethod} with a valid implementation + * @throws RuntimeException if no implementation was found + */ + public UnboundMethod build() { + if (method != null) { + return method; + } else { + throw new RuntimeException("Cannot find method: " + name); + } + } + + /** + * Returns the first valid implementation as a BoundMethod or throws a RuntimeError if there is + * none. + * + * @param receiver an Object to receive the method invocation + * @return a {@link BoundMethod} with a valid implementation and receiver + * @throws IllegalStateException if the method is static + * @throws IllegalArgumentException if the receiver's class is incompatible + * @throws RuntimeException if no implementation was found + */ + public BoundMethod build(Object receiver) { + return build().bind(receiver); + } + + /** + * Returns the first valid implementation as a UnboundMethod or throws a NoSuchMethodException + * if there is none. + * + * @return a {@link UnboundMethod} with a valid implementation + * @throws NoSuchMethodException if no implementation was found + */ + public UnboundMethod buildChecked() throws NoSuchMethodException { + if (method != null) { + return method; + } else { + throw new NoSuchMethodException("Cannot find method: " + name); + } + } + + /** + * Returns the first valid implementation as a BoundMethod or throws a NoSuchMethodException if + * there is none. + * + * @param receiver an Object to receive the method invocation + * @return a {@link BoundMethod} with a valid implementation and receiver + * @throws IllegalStateException if the method is static + * @throws IllegalArgumentException if the receiver's class is incompatible + * @throws NoSuchMethodException if no implementation was found + */ + public BoundMethod buildChecked(Object receiver) throws NoSuchMethodException { + return buildChecked().bind(receiver); + } + + /** + * Returns the first valid implementation as a StaticMethod or throws a NoSuchMethodException if + * there is none. + * + * @return a {@link StaticMethod} with a valid implementation + * @throws IllegalStateException if the method is not static + * @throws NoSuchMethodException if no implementation was found + */ + public StaticMethod buildStaticChecked() throws NoSuchMethodException { + return buildChecked().asStatic(); + } + + /** + * Returns the first valid implementation as a StaticMethod or throws a RuntimeException if + * there is none. + * + * @return a {@link StaticMethod} with a valid implementation + * @throws IllegalStateException if the method is not static + * @throws RuntimeException if no implementation was found + */ + public StaticMethod buildStatic() { + return build().asStatic(); + } + } + + private static class MakeAccessible implements PrivilegedAction { + private final Method hidden; + + MakeAccessible(Method hidden) { + this.hidden = hidden; + } + + @Override + public Void run() { + hidden.setAccessible(true); + return null; + } + } +} diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3ClientPool.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3ClientPool.java index 8e9f858..cf276ad 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3ClientPool.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3ClientPool.java @@ -13,9 +13,6 @@ */ package org.lance.namespace.hive3; -import org.lance.namespace.util.ClientPoolImpl; -import org.lance.namespace.util.DynMethods; - import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.HiveMetaHookLoader; diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java index 3f46207..dcc4dfc 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java @@ -13,38 +13,32 @@ */ package org.lance.namespace.hive3; -import com.lancedb.lance.Dataset; -import com.lancedb.lance.WriteParams; -import org.lance.namespace.Configurable; +import org.lance.Dataset; +import org.lance.WriteParams; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.ObjectIdentifier; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.ServiceUnavailableException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; -import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; import org.lance.namespace.model.NamespaceExistsRequest; import org.lance.namespace.model.TableExistsRequest; -import org.lance.namespace.util.ArrowIpcUtil; -import org.lance.namespace.util.CommonUtil; -import org.lance.namespace.util.JsonArrowSchemaConverter; -import org.lance.namespace.util.PageUtil; -import org.lance.namespace.util.ValidationUtil; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -61,19 +55,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import static org.lance.namespace.hive3.Hive3ErrorType.DatabaseAlreadyExist; -import static org.lance.namespace.hive3.Hive3ErrorType.HiveMetaStoreError; -import static org.lance.namespace.hive3.Hive3ErrorType.TableAlreadyExists; -import static org.lance.namespace.hive3.Hive3ErrorType.TableNotFound; - -public class Hive3Namespace implements LanceNamespace, Configurable { +public class Hive3Namespace implements LanceNamespace { private static final Logger LOG = LoggerFactory.getLogger(Hive3Namespace.class); private Hive3ClientPool clientPool; @@ -83,6 +71,11 @@ public class Hive3Namespace implements LanceNamespace, Configurable configProperties, BufferAllocator allocator) { this.allocator = allocator; @@ -126,7 +119,7 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { @Override public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { ObjectIdentifier id = ObjectIdentifier.of(request.getId()); - CreateNamespaceRequest.ModeEnum mode = request.getMode(); + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "create"; Map properties = request.getProperties(); ValidationUtil.checkArgument( @@ -154,11 +147,8 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ Catalog catalogObj = Hive3Util.getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { - throw LanceNamespaceException.notFound( - String.format("Namespace does not exist: %s", id.stringStyleId()), - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Namespace does not exist: %s", id.stringStyleId())); } if (catalogObj.getDescription() != null) { @@ -173,11 +163,8 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ Database database = Hive3Util.getDatabaseOrNull(clientPool, catalog, db); if (database == null) { - throw LanceNamespaceException.notFound( - String.format("Namespace does not exist: %s", id.stringStyleId()), - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Namespace does not exist: %s", id.stringStyleId())); } if (database.getDescription() != null) { @@ -214,11 +201,8 @@ public void namespaceExists(NamespaceExistsRequest request) { Catalog catalogObj = Hive3Util.getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { - throw LanceNamespaceException.notFound( - String.format("Namespace does not exist: %s", id.stringStyleId()), - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Namespace does not exist: %s", id.stringStyleId())); } } else { String catalog = id.levelAtListPos(0).toLowerCase(); @@ -226,11 +210,8 @@ public void namespaceExists(NamespaceExistsRequest request) { Database database = Hive3Util.getDatabaseOrNull(clientPool, catalog, db); if (database == null) { - throw LanceNamespaceException.notFound( - String.format("Namespace does not exist: %s", id.stringStyleId()), - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Namespace does not exist: %s", id.stringStyleId())); } } } @@ -238,20 +219,12 @@ public void namespaceExists(NamespaceExistsRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ObjectIdentifier id = ObjectIdentifier.of(request.getId()); - DropNamespaceRequest.ModeEnum mode = request.getMode(); - DropNamespaceRequest.BehaviorEnum behavior = request.getBehavior(); + String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; ValidationUtil.checkArgument( !id.isRoot() && id.levels() <= 2, "Expect a 2-level namespace but get %s", id); - if (mode == null) { - mode = DropNamespaceRequest.ModeEnum.FAIL; - } - if (behavior == null) { - behavior = DropNamespaceRequest.BehaviorEnum.RESTRICT; - } - - Map properties = doDropNamespace(id, mode, behavior); + Map properties = doDropNamespace(id, mode); DropNamespaceResponse response = new DropNamespaceResponse(); response.setProperties(properties); @@ -272,11 +245,8 @@ public void tableExists(TableExistsRequest request) { Optional

hmsTable = Hive3Util.getTable(clientPool, catalog, db, table); if (!hmsTable.isPresent()) { - throw LanceNamespaceException.notFound( - String.format("Table does not exist: %s", tableId.stringStyleId()), - TableNotFound.getType(), - tableId.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new TableNotFoundException( + String.format("Table does not exist: %s", tableId.stringStyleId())); } Hive3Util.validateLanceTable(hmsTable.get()); @@ -314,11 +284,8 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { Optional location = doDescribeTable(tableId); if (!location.isPresent()) { - throw LanceNamespaceException.notFound( - String.format("Table does not exist: %s", tableId.stringStyleId()), - TableNotFound.getType(), - tableId.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new TableNotFoundException( + String.format("Table does not exist: %s", tableId.stringStyleId())); } DescribeTableResponse response = new DescribeTableResponse(); @@ -326,46 +293,7 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { return response; } - @Override - public CreateTableResponse createTable(CreateTableRequest request, byte[] requestData) { - // Validate that requestData is a valid Arrow IPC stream - ValidationUtil.checkNotNull( - requestData, "Request data (Arrow IPC stream) is required for createTable"); - ValidationUtil.checkArgument( - requestData.length > 0, "Request data (Arrow IPC stream) cannot be empty"); - - ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); - - // Extract schema from Arrow IPC stream - JsonArrowSchema jsonSchema; - try { - jsonSchema = ArrowIpcUtil.extractSchemaFromIpc(requestData); - } catch (IOException e) { - throw LanceNamespaceException.badRequest( - "Invalid Arrow IPC stream: " + e.getMessage(), - "INVALID_ARROW_IPC", - tableId.stringStyleId(), - "Failed to extract schema from Arrow IPC stream"); - } - Schema schema = JsonArrowSchemaConverter.convertToArrowSchema(jsonSchema); - - ValidationUtil.checkArgument( - tableId.levels() == 3, "Expect 3-level table identifier but get %s", tableId); - - String location = request.getLocation(); - if (location == null || location.isEmpty()) { - location = - getDefaultTableLocation( - tableId.levelAtListPos(0), tableId.levelAtListPos(1), tableId.levelAtListPos(2)); - } - - doCreateTable(tableId, schema, location, request.getProperties(), requestData); - - CreateTableResponse response = new CreateTableResponse(); - response.setLocation(location); - response.setVersion(1L); - return response; - } + // Removed: createTable(CreateTableRequest, byte[]) - using default implementation from interface @Override public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { @@ -381,31 +309,16 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request tableId.levelAtListPos(0), tableId.levelAtListPos(1), tableId.levelAtListPos(2)); } - // Create table in metastore without data (pass null for requestData) - doCreateTable(tableId, null, location, request.getProperties(), null); + // Create table in metastore without data (pass null for requestData and properties) + doCreateTable(tableId, null, location, null, null); CreateEmptyTableResponse response = new CreateEmptyTableResponse(); response.setLocation(location); return response; } - @Override - public DropTableResponse dropTable(DropTableRequest request) { - ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); - - ValidationUtil.checkArgument( - tableId.levels() == 3, "Expect 3-level table identifier but get %s", tableId); - - String location = doDropTable(tableId); - // TODO: remove data + // Removed: dropTable(DropTableRequest) - using default implementation from interface - DropTableResponse response = new DropTableResponse(); - response.setLocation(location); - response.setId(request.getId()); - return response; - } - - @Override public void setConf(Configuration conf) { this.hadoopConf = conf; } @@ -424,16 +337,12 @@ protected List doListNamespaces(ObjectIdentifier parent) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed operation: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException("Failed operation: " + errorMessage); } } protected void doCreateNamespace( - ObjectIdentifier id, CreateNamespaceRequest.ModeEnum mode, Map properties) { + ObjectIdentifier id, String mode, Map properties) { try { if (id.levels() == 1) { @@ -449,35 +358,26 @@ protected void doCreateNamespace( Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed operation: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException("Failed operation: " + errorMessage); } } - private void createCatalog( - String catalogName, CreateNamespaceRequest.ModeEnum mode, Map properties) + private void createCatalog(String catalogName, String mode, Map properties) throws TException, InterruptedException { Catalog existingCatalog = Hive3Util.getCatalogOrNull(clientPool, catalogName); if (existingCatalog != null) { - switch (mode) { - case CREATE: - throw LanceNamespaceException.conflict( - String.format("Catalog %s already exists", catalogName), - DatabaseAlreadyExist.getType(), - "", - CommonUtil.formatCurrentStackTrace()); - case EXIST_OK: - return; - case OVERWRITE: - clientPool.run( - client -> { - client.dropCatalog(catalogName); - return null; - }); + if ("create".equals(mode)) { + throw new NamespaceAlreadyExistsException( + String.format("Catalog %s already exists", catalogName)); + } else if ("exist_ok".equals(mode) || "existok".equals(mode)) { + return; + } else if ("overwrite".equals(mode)) { + clientPool.run( + client -> { + client.dropCatalog(catalogName); + return null; + }); } } @@ -506,30 +406,23 @@ private void createCatalog( } private void createDatabase( - String catalogName, - String dbName, - CreateNamespaceRequest.ModeEnum mode, - Map properties) + String catalogName, String dbName, String mode, Map properties) throws TException, InterruptedException { Catalog catalog = Hive3Util.getCatalogOrThrowNotFoundException(clientPool, catalogName); Database oldDb = Hive3Util.getDatabaseOrNull(clientPool, catalogName, dbName); if (oldDb != null) { - switch (mode) { - case CREATE: - throw LanceNamespaceException.conflict( - String.format("Database %s.%s already exist", catalogName, dbName), - DatabaseAlreadyExist.getType(), - "", - CommonUtil.formatCurrentStackTrace()); - case EXIST_OK: - return; - case OVERWRITE: - clientPool.run( - client -> { - client.dropDatabase(catalogName, dbName, false, true, false); - return null; - }); + if ("create".equals(mode)) { + throw new NamespaceAlreadyExistsException( + String.format("Database %s.%s already exist", catalogName, dbName)); + } else if ("exist_ok".equals(mode) || "existok".equals(mode)) { + return; + } else if ("overwrite".equals(mode)) { + clientPool.run( + client -> { + client.dropDatabase(catalogName, dbName, false, true, false); + return null; + }); } } @@ -580,11 +473,8 @@ protected void doCreateTable( try { Optional
existing = Hive3Util.getTable(clientPool, catalog, db, tableName); if (existing.isPresent()) { - throw LanceNamespaceException.conflict( - String.format("Table %s.%s.%s already exists", catalog, db, tableName), - TableAlreadyExists.getType(), - String.format("%s.%s.%s", catalog, db, tableName), - CommonUtil.formatCurrentStackTrace()); + throw new TableAlreadyExistsException( + String.format("Table %s.%s.%s already exists", catalog, db, tableName)); } Table table = new Table(); @@ -614,11 +504,7 @@ protected void doCreateTable( if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serverError( - "Fail to create table: " + e.getMessage(), - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new InternalException("Fail to create table: " + e.getMessage()); } if (data != null && data.length > 0) { @@ -636,20 +522,13 @@ protected List doListTables(String catalog, String db) { // First validate that catalog and database exist Catalog catalogObj = Hive3Util.getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { - throw LanceNamespaceException.notFound( - String.format("Catalog %s doesn't exist", catalog), - HiveMetaStoreError.getType(), - catalog, - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException(String.format("Catalog %s doesn't exist", catalog)); } Database database = Hive3Util.getDatabaseOrNull(clientPool, catalog, db); if (database == null) { - throw LanceNamespaceException.notFound( - String.format("Database %s.%s doesn't exist", catalog, db), - HiveMetaStoreError.getType(), - String.format("%s.%s", catalog, db), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Database %s.%s doesn't exist", catalog, db)); } List allTables = clientPool.run(client -> client.getAllTables(catalog, db)); @@ -676,11 +555,7 @@ protected List doListTables(String catalog, String db) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to list tables: " + errorMessage, - HiveMetaStoreError.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException("Failed to list tables: " + errorMessage); } } @@ -692,11 +567,8 @@ protected String doDropTable(ObjectIdentifier id) { try { Optional
hmsTable = Hive3Util.getTable(clientPool, catalog, db, tableName); if (!hmsTable.isPresent()) { - throw LanceNamespaceException.notFound( - String.format("Table %s.%s.%s does not exist", catalog, db, tableName), - TableNotFound.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new TableNotFoundException( + String.format("Table %s.%s.%s does not exist", catalog, db, tableName)); } Hive3Util.validateLanceTable(hmsTable.get()); @@ -714,92 +586,48 @@ protected String doDropTable(ObjectIdentifier id) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to drop table: " + errorMessage, - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException("Failed to drop table: " + errorMessage); } } - protected Map doDropNamespace( - ObjectIdentifier id, - DropNamespaceRequest.ModeEnum mode, - DropNamespaceRequest.BehaviorEnum behavior) { + protected Map doDropNamespace(ObjectIdentifier id, String mode) { try { if (id.levels() == 1) { // Drop catalog - return doDropCatalog(id.levelAtListPos(0).toLowerCase(), mode, behavior); + return doDropCatalog(id.levelAtListPos(0).toLowerCase(), mode); } else { // Drop database return doDropDatabase( - id.levelAtListPos(0).toLowerCase(), id.levelAtListPos(1).toLowerCase(), mode, behavior); + id.levelAtListPos(0).toLowerCase(), id.levelAtListPos(1).toLowerCase(), mode); } } catch (TException | InterruptedException e) { if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } String errorMessage = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName(); - throw LanceNamespaceException.serviceUnavailable( - "Failed to drop namespace: " + errorMessage, - HiveMetaStoreError.getType(), - id.stringStyleId(), - CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException("Failed to drop namespace: " + errorMessage); } } - private Map doDropCatalog( - String catalog, - DropNamespaceRequest.ModeEnum mode, - DropNamespaceRequest.BehaviorEnum behavior) + private Map doDropCatalog(String catalog, String mode) throws TException, InterruptedException { Catalog catalogObj = Hive3Util.getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { - if (mode == DropNamespaceRequest.ModeEnum.SKIP) { + if ("skip".equals(mode)) { return new HashMap<>(); } else { - throw LanceNamespaceException.notFound( - String.format("Catalog %s doesn't exist", catalog), - HiveMetaStoreError.getType(), - catalog, - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException(String.format("Catalog %s doesn't exist", catalog)); } } - // Check for child databases + // Check for child databases (RESTRICT mode only) List databases = clientPool.run(client -> client.getAllDatabases(catalog)); if (!databases.isEmpty()) { - if (behavior == DropNamespaceRequest.BehaviorEnum.RESTRICT) { - throw LanceNamespaceException.badRequest( - String.format( - "Catalog %s is not empty. Contains %d databases: %s", - catalog, databases.size(), databases), - HiveMetaStoreError.getType(), - catalog, - CommonUtil.formatCurrentStackTrace()); - } else if (behavior == DropNamespaceRequest.BehaviorEnum.CASCADE) { - // Drop all databases first - for (String dbName : databases) { - try { - doDropDatabase( - catalog, - dbName, - DropNamespaceRequest.ModeEnum.FAIL, - DropNamespaceRequest.BehaviorEnum.CASCADE); - LOG.info("Dropped database {}.{} during CASCADE operation", catalog, dbName); - } catch (Exception e) { - LOG.warn("Failed to drop database {}.{}: {}", catalog, dbName, e.getMessage()); - throw LanceNamespaceException.serviceUnavailable( - String.format( - "Failed to drop database %s.%s during CASCADE operation: %s", - catalog, dbName, e.getMessage()), - HiveMetaStoreError.getType(), - String.format("%s.%s", catalog, dbName), - CommonUtil.formatCurrentStackTrace()); - } - } - } + throw new InvalidInputException( + String.format( + "Catalog %s is not empty. Contains %d databases: %s", + catalog, databases.size(), databases)); } // Collect catalog properties @@ -822,56 +650,25 @@ private Map doDropCatalog( return properties; } - private Map doDropDatabase( - String catalog, - String db, - DropNamespaceRequest.ModeEnum mode, - DropNamespaceRequest.BehaviorEnum behavior) + private Map doDropDatabase(String catalog, String db, String mode) throws TException, InterruptedException { Database database = Hive3Util.getDatabaseOrNull(clientPool, catalog, db); if (database == null) { - if (mode == DropNamespaceRequest.ModeEnum.SKIP) { + if ("skip".equals(mode)) { return new HashMap<>(); } else { - throw LanceNamespaceException.notFound( - String.format("Database %s.%s doesn't exist", catalog, db), - HiveMetaStoreError.getType(), - String.format("%s.%s", catalog, db), - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException( + String.format("Database %s.%s doesn't exist", catalog, db)); } } - // Check if database contains tables + // Check if database contains tables (RESTRICT mode only) List tables = doListTables(catalog, db); if (!tables.isEmpty()) { - if (behavior == DropNamespaceRequest.BehaviorEnum.RESTRICT) { - throw LanceNamespaceException.badRequest( - String.format( - "Database %s.%s is not empty. Contains %d tables: %s", - catalog, db, tables.size(), tables), - HiveMetaStoreError.getType(), - String.format("%s.%s", catalog, db), - CommonUtil.formatCurrentStackTrace()); - } else if (behavior == DropNamespaceRequest.BehaviorEnum.CASCADE) { - // Drop all tables first - for (String tableName : tables) { - try { - ObjectIdentifier tableId = - ObjectIdentifier.of(Lists.newArrayList(catalog, db, tableName)); - doDropTable(tableId); - LOG.info("Dropped table {}.{}.{} during CASCADE operation", catalog, db, tableName); - } catch (Exception e) { - LOG.warn("Failed to drop table {}.{}.{}: {}", catalog, db, tableName, e.getMessage()); - throw LanceNamespaceException.serviceUnavailable( - String.format( - "Failed to drop table %s.%s.%s during CASCADE operation: %s", - catalog, db, tableName, e.getMessage()), - HiveMetaStoreError.getType(), - String.format("%s.%s.%s", catalog, db, tableName), - CommonUtil.formatCurrentStackTrace()); - } - } - } + throw new InvalidInputException( + String.format( + "Database %s.%s is not empty. Contains %d tables: %s", + catalog, db, tables.size(), tables)); } // Collect database properties diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3NamespaceConfig.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3NamespaceConfig.java index 243cd8b..c5ba2a2 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3NamespaceConfig.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3NamespaceConfig.java @@ -13,9 +13,7 @@ */ package org.lance.namespace.hive3; -import org.lance.namespace.util.OpenDalUtil; -import org.lance.namespace.util.PropertyUtil; - +import java.util.HashMap; import java.util.Map; public class Hive3NamespaceConfig { @@ -42,12 +40,27 @@ public class Hive3NamespaceConfig { private final String root; public Hive3NamespaceConfig(Map properties) { + // Inline PropertyUtil.propertyAsInt + String clientPoolSizeStr = properties.get(CLIENT_POOL_SIZE); this.clientPoolSize = - PropertyUtil.propertyAsInt(properties, CLIENT_POOL_SIZE, CLIENT_POOL_SIZE_DEFAULT); - this.storageOptions = PropertyUtil.propertiesWithPrefix(properties, STORAGE_OPTIONS_PREFIX); + clientPoolSizeStr != null ? Integer.parseInt(clientPoolSizeStr) : CLIENT_POOL_SIZE_DEFAULT; + + // Inline PropertyUtil.propertiesWithPrefix + Map filteredStorageOptions = new HashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + if (entry.getKey().startsWith(STORAGE_OPTIONS_PREFIX)) { + filteredStorageOptions.put( + entry.getKey().substring(STORAGE_OPTIONS_PREFIX.length()), entry.getValue()); + } + } + this.storageOptions = filteredStorageOptions; + + // Inline PropertyUtil.propertyAsString and OpenDalUtil.stripTrailingSlash + String rootValue = properties.getOrDefault(ROOT, ROOT_DEFAULT); this.root = - OpenDalUtil.stripTrailingSlash( - PropertyUtil.propertyAsString(properties, ROOT, ROOT_DEFAULT)); + rootValue != null && rootValue.endsWith("/") + ? rootValue.substring(0, rootValue.length() - 1) + : rootValue; } public int getClientPoolSize() { diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Util.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Util.java index 245ec9b..b77eb89 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Util.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Util.java @@ -13,8 +13,9 @@ */ package org.lance.namespace.hive3; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.util.CommonUtil; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.ServiceUnavailableException; import com.google.common.collect.Maps; import org.apache.hadoop.hive.metastore.api.Catalog; @@ -31,10 +32,6 @@ import java.util.Optional; import java.util.function.Supplier; -import static org.lance.namespace.hive3.Hive3ErrorType.HiveMetaStoreError; -import static org.lance.namespace.hive3.Hive3ErrorType.InvalidLanceTable; -import static org.lance.namespace.hive3.Hive3ErrorType.UnknownCatalog; - public class Hive3Util { public static Catalog getCatalogOrNull(Hive3ClientPool clientPool, String catalog) { try { @@ -45,8 +42,7 @@ public static Catalog getCatalogOrNull(Hive3ClientPool clientPool, String catalo if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage()); } } @@ -54,11 +50,7 @@ public static Catalog getCatalogOrThrowNotFoundException( Hive3ClientPool clientPool, String catalog) { Catalog catalogObj = getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { - throw LanceNamespaceException.notFound( - String.format("Catalog %s doesn't exist", catalog), - UnknownCatalog.getType(), - "", - CommonUtil.formatCurrentStackTrace()); + throw new NamespaceNotFoundException(String.format("Catalog %s doesn't exist", catalog)); } return catalogObj; } @@ -72,8 +64,7 @@ public static Database getDatabaseOrNull(Hive3ClientPool clientPool, String cata if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage()); } } @@ -86,8 +77,7 @@ public static Database getDatabaseOrNull(Hive3ClientPool clientPool, String db) if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage()); } } @@ -151,8 +141,7 @@ public static Optional
getTable(Hive3ClientPool clientPool, String db, St if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage()); } } @@ -166,20 +155,16 @@ public static Optional
getTable( if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } - throw LanceNamespaceException.serviceUnavailable( - e.getMessage(), HiveMetaStoreError.getType(), "", CommonUtil.formatCurrentStackTrace()); + throw new ServiceUnavailableException(e.getMessage()); } } public static void validateLanceTable(Table table) { Map params = table.getParameters(); if (params == null || !"lance".equalsIgnoreCase(params.get("table_type"))) { - throw LanceNamespaceException.badRequest( + throw new InvalidInputException( String.format( - "Table %s.%s is not a Lance table", table.getDbName(), table.getTableName()), - InvalidLanceTable.getType(), - String.format("%s.%s", table.getDbName(), table.getTableName()), - CommonUtil.formatCurrentStackTrace()); + "Table %s.%s is not a Lance table", table.getDbName(), table.getTableName())); } } diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ObjectIdentifier.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ObjectIdentifier.java new file mode 100644 index 0000000..cfd5e36 --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ObjectIdentifier.java @@ -0,0 +1,55 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +import java.util.Collections; +import java.util.List; + +/** Represents a hierarchical identifier for namespaces and tables. */ +public class ObjectIdentifier { + private final List levels; + + private ObjectIdentifier(List levels) { + this.levels = levels != null ? levels : Collections.emptyList(); + } + + public static ObjectIdentifier of(List levels) { + return new ObjectIdentifier(levels); + } + + public boolean isRoot() { + return levels.isEmpty(); + } + + public int levels() { + return levels.size(); + } + + public String levelAtListPos(int pos) { + if (pos < 0 || pos >= levels.size()) { + throw new IndexOutOfBoundsException( + "Position " + pos + " is out of bounds for size " + levels.size()); + } + return levels.get(pos); + } + + public String stringStyleId() { + return String.join(".", levels); + } + + @Override + public String toString() { + return stringStyleId(); + } +} diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/PageUtil.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/PageUtil.java new file mode 100644 index 0000000..62475cc --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/PageUtil.java @@ -0,0 +1,70 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +import java.util.List; + +/** Utility methods for pagination. */ +public class PageUtil { + + private static final int DEFAULT_PAGE_SIZE = 100; + + private PageUtil() {} + + public static int normalizePageSize(Integer pageSize) { + if (pageSize == null || pageSize <= 0) { + return DEFAULT_PAGE_SIZE; + } + return pageSize; + } + + public static Page splitPage(List items, String pageToken, int pageSize) { + int startIndex = 0; + if (pageToken != null && !pageToken.isEmpty()) { + try { + startIndex = Integer.parseInt(pageToken); + } catch (NumberFormatException e) { + startIndex = 0; + } + } + + if (startIndex >= items.size()) { + return new Page(java.util.Collections.emptyList(), null); + } + + int endIndex = Math.min(startIndex + pageSize, items.size()); + List pageItems = items.subList(startIndex, endIndex); + + String nextPageToken = endIndex < items.size() ? String.valueOf(endIndex) : null; + return new Page(pageItems, nextPageToken); + } + + public static class Page { + private final List items; + private final String nextPageToken; + + public Page(List items, String nextPageToken) { + this.items = items; + this.nextPageToken = nextPageToken; + } + + public List items() { + return items; + } + + public String nextPageToken() { + return nextPageToken; + } + } +} diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ValidationUtil.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ValidationUtil.java new file mode 100644 index 0000000..c2dbc3a --- /dev/null +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/ValidationUtil.java @@ -0,0 +1,35 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.hive3; + +import org.lance.namespace.errors.InvalidInputException; + +/** Utility methods for validation. */ +public class ValidationUtil { + + private ValidationUtil() {} + + public static void checkArgument(boolean expression, String message, Object... args) { + if (!expression) { + throw new InvalidInputException(String.format(message, args)); + } + } + + public static String checkNotNullOrEmptyString(String value, String message) { + if (value == null || value.isEmpty()) { + throw new InvalidInputException(message); + } + return value; + } +} diff --git a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java index 9ae66c4..42724d4 100644 --- a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java +++ b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java @@ -14,20 +14,13 @@ package org.lance.namespace.hive3; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.LanceNamespaces; -import org.lance.namespace.TestHelper; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; -import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; import org.lance.namespace.model.NamespaceExistsRequest; @@ -41,7 +34,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.io.File; @@ -74,7 +66,10 @@ public static void setup() throws IOException { tmpDirBase = file.getAbsolutePath(); HiveConf hiveConf = metastore.hiveConf(); - namespace = LanceNamespaces.connect("hive3", Maps.newHashMap(), hiveConf, allocator); + Hive3Namespace hive3Namespace = new Hive3Namespace(); + hive3Namespace.setHadoopConf(hiveConf); + hive3Namespace.initialize(Maps.newHashMap(), allocator); + namespace = hive3Namespace; // Setup: Create catalog and database for tests CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); @@ -82,7 +77,7 @@ public static void setup() throws IOException { properties.put("catalog.location.uri", "file://" + tmpDirBase + "/test_catalog"); nsRequest.setProperties(properties); nsRequest.setId(Lists.list("test_catalog")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); nsRequest.setId(Lists.list("test_catalog", "test_db")); @@ -114,97 +109,13 @@ public void cleanup() throws Exception { properties.put("catalog.location.uri", "file://" + tmpDirBase + "/test_catalog"); nsRequest.setProperties(properties); nsRequest.setId(Lists.list("test_catalog")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); namespace.createNamespace(nsRequest); nsRequest.setId(Lists.list("test_catalog", "test_db")); namespace.createNamespace(nsRequest); } - @Disabled("Need to figure out the proper interface") - @Test - public void testCreateTable() throws IOException { - // Test: Create table with valid parameters - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "test_table")); - request.setLocation(tmpDirBase + "/test_catalog/test_db/test_table.lance"); - - Map properties = Maps.newHashMap(); - properties.put("custom_prop", "custom_value"); - request.setProperties(properties); - - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = namespace.createTable(request, testData); - - assertEquals(request.getLocation(), response.getLocation()); - assertEquals(1L, response.getVersion()); - } - - @Test - public void testCreateTableAlreadyExists() throws IOException { - // Setup: Create table - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "test_table")); - request.setLocation(tmpDirBase + "/test_catalog/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(request, testData); - - // Test: Create table that already exists - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.createTable(request, testData)); - assertTrue(error.getMessage().contains("Table test_catalog.test_db.test_table already exists")); - } - - @Test - public void testCreateTableManagedByImpl() throws IOException { - // Test: Create table with managed_by=impl (not supported) - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "impl_table")); - request.setLocation(tmpDirBase + "/test_catalog/test_db/impl_table.lance"); - - Map properties = Maps.newHashMap(); - properties.put("managed_by", "impl"); - request.setProperties(properties); - - byte[] testData = TestHelper.createTestArrowData(allocator); - Exception error = - assertThrows( - UnsupportedOperationException.class, () -> namespace.createTable(request, testData)); - assertTrue(error.getMessage().contains("managed_by=impl is not supported yet")); - } - - @Test - public void testCreateTableWithoutData() throws IOException { - // Test: Create table without data - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "no_data_table")); - request.setLocation(tmpDirBase + "/test_catalog/test_db/no_data_table.lance"); - - byte[] emptyData = TestHelper.createEmptyArrowData(allocator); - CreateTableResponse response = namespace.createTable(request, emptyData); - assertEquals(request.getLocation(), response.getLocation()); - } - - @Test - public void testDescribeTable() throws IOException { - // Setup: Create table - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog", "test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Describe existing Lance table - DescribeTableRequest request = new DescribeTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "test_table")); - - DescribeTableResponse response = namespace.describeTable(request); - assertEquals( - "file:" + tmpDirBase + "/test_catalog/test_db/test_table.lance", response.getLocation()); - } - @Test public void testDescribeNonExistentTable() { // Test: Describe non-existent table @@ -215,131 +126,6 @@ public void testDescribeNonExistentTable() { assertTrue(error.getMessage().contains("Table does not exist")); } - @Test - public void testDropTable() throws IOException { - // Setup: Create table - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog", "test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Drop existing table - DropTableRequest request = new DropTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "test_table")); - - DropTableResponse response = namespace.dropTable(request); - assertEquals( - "file:" + tmpDirBase + "/test_catalog/test_db/test_table.lance", response.getLocation()); - assertEquals(request.getId(), response.getId()); - - // Verify table is dropped by trying to describe it - DescribeTableRequest descRequest = new DescribeTableRequest(); - descRequest.setId(request.getId()); - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.describeTable(descRequest)); - assertTrue(error.getMessage().contains("Table does not exist")); - } - - @Test - public void testDropNonExistentTable() { - // Test: Drop non-existent table - DropTableRequest request = new DropTableRequest(); - request.setId(Lists.list("test_catalog", "test_db", "non_existent")); - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.dropTable(request)); - assertTrue( - error.getMessage().contains("Table test_catalog.test_db.non_existent does not exist")); - } - - @Test - public void testCreateTableWithDefaultLocationFromRoot() throws IOException { - // With our enhancement, databases created without explicit location - // will use the root config location instead of Hive warehouse - - // Setup: Create namespace with custom root configuration - Map properties = Maps.newHashMap(); - properties.put("root", tmpDirBase); - - HiveConf hiveConf = metastore.hiveConf(); - LanceNamespace customNamespace = - LanceNamespaces.connect("hive3", properties, hiveConf, allocator); - - // Setup: Create database (will use root location) - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_catalog", "test_db_root")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - customNamespace.createNamespace(nsRequest); - - // Test: Create table without specifying location - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db_root", "test_table")); - // Don't set location - it will be derived from database location - - // Create test Arrow IPC data - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = customNamespace.createTable(request, testData); - - // Verify: Location should be derived from root-based database location - // Note: The location may or may not have file: prefix depending on how Hive processes it - String expectedLocation = tmpDirBase + "/test_db_root/test_table.lance"; - assertTrue( - response.getLocation().equals(expectedLocation) - || response.getLocation().equals("file:" + expectedLocation), - "Expected location (with or without file: prefix): " - + expectedLocation - + " but got: " - + response.getLocation()); - assertEquals(1L, response.getVersion()); - } - - @Test - public void testCreateTableWithExplicitDatabaseLocation() throws IOException { - // Note: This test verifies that when a database location is explicitly set, - // it takes precedence over the root config. However, the current implementation - // may fall back to root config if database location retrieval fails. - - // Setup: Create namespace with custom root configuration - Map properties = Maps.newHashMap(); - properties.put("root", tmpDirBase); - - HiveConf hiveConf = metastore.hiveConf(); - LanceNamespace customNamespace = - LanceNamespaces.connect("hive3", properties, hiveConf, allocator); - - // Setup: Create database with specific location - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_catalog", "test_db_with_location")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - - // Set database location - this should take precedence over root config - String databaseLocation = tmpDirBase + "/custom_db_location"; - Map dbProperties = Maps.newHashMap(); - dbProperties.put("database.location-uri", databaseLocation); - nsRequest.setProperties(dbProperties); - - customNamespace.createNamespace(nsRequest); - - // Test: Create table without specifying location - CreateTableRequest request = new CreateTableRequest(); - request.setId(Lists.list("test_catalog", "test_db_with_location", "test_table")); - // Don't set location - should be derived from database location or root fallback - - // Create test Arrow IPC data - byte[] testData = TestHelper.createTestArrowData(allocator); - CreateTableResponse response = customNamespace.createTable(request, testData); - - // Verify: Location should be derived from either database location or root fallback - // For now, accept either pattern until database location retrieval is fixed - assertTrue( - response.getLocation().contains("custom_db_location/test_table.lance") - || response.getLocation().contains("test_db_with_location/test_table.lance"), - "Expected either custom database location or root fallback but got: " - + response.getLocation()); - assertEquals(1L, response.getVersion()); - } - @Test public void testDescribeNamespaceCatalog() { // Test: Describe catalog-level namespace @@ -370,7 +156,7 @@ public void testDescribeNamespaceDatabaseWithCustomProperties() { // Setup: Create database with custom properties CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Lists.list("test_catalog", "custom_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + nsRequest.setMode("Create"); Map properties = Maps.newHashMap(); properties.put("database.description", "Custom database description"); @@ -457,24 +243,6 @@ public void testNamespaceExistsNonExistentDatabase() { assertTrue(error.getMessage().contains("Namespace does not exist")); } - @Test - public void testTableExists() throws IOException { - // Setup: Create table - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog", "test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Check existing table - TableExistsRequest request = new TableExistsRequest(); - request.setId(Lists.list("test_catalog", "test_db", "test_table")); - - // Should not throw exception for existing Lance table - namespace.tableExists(request); - } - @Test public void testTableExistsNonExistent() { // Test: Check non-existent table @@ -486,34 +254,6 @@ public void testTableExistsNonExistent() { assertTrue(error.getMessage().contains("Table does not exist")); } - @Test - public void testListTables() throws IOException { - // Create first table - CreateTableRequest createRequest1 = new CreateTableRequest(); - createRequest1.setId(Lists.list("test_catalog", "test_db", "table1")); - createRequest1.setLocation(tmpDirBase + "/test_catalog/test_db/table1.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest1, testData); - - // Create second table - CreateTableRequest createRequest2 = new CreateTableRequest(); - createRequest2.setId(Lists.list("test_catalog", "test_db", "table2")); - createRequest2.setLocation(tmpDirBase + "/test_catalog/test_db/table2.lance"); - - namespace.createTable(createRequest2, testData); - - // Test: List tables - ListTablesRequest request = new ListTablesRequest(); - request.setId(Lists.list("test_catalog", "test_db")); - - ListTablesResponse response = namespace.listTables(request); - - assertEquals(2, response.getTables().size()); - assertTrue(response.getTables().contains("table1")); - assertTrue(response.getTables().contains("table2")); - } - @Test public void testListTablesEmpty() { // Test: List tables in empty database @@ -525,67 +265,6 @@ public void testListTablesEmpty() { assertEquals(0, response.getTables().size()); } - @Test - public void testListTablesWithPagination() throws IOException { - // Create multiple tables - for (int i = 1; i <= 5; i++) { - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog", "test_db", "table" + i)); - createRequest.setLocation(tmpDirBase + "/test_catalog/test_db/table" + i + ".lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - } - - // Test: List tables with pagination (limit 3) - ListTablesRequest request = new ListTablesRequest(); - request.setId(Lists.list("test_catalog", "test_db")); - request.setLimit(3); - - ListTablesResponse response = namespace.listTables(request); - - assertEquals(3, response.getTables().size()); - // Should have a page token for remaining results - assertTrue(response.getPageToken() != null && !response.getPageToken().isEmpty()); - - // Get remaining tables - ListTablesRequest nextRequest = new ListTablesRequest(); - nextRequest.setId(Lists.list("test_catalog", "test_db")); - nextRequest.setPageToken(response.getPageToken()); - - ListTablesResponse nextResponse = namespace.listTables(nextRequest); - - assertEquals(2, nextResponse.getTables().size()); - // No more pages - assertTrue(nextResponse.getPageToken() == null || nextResponse.getPageToken().isEmpty()); - } - - @Test - public void testListTablesWithCustomDatabase() throws IOException { - // Setup: Create database with custom name - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Lists.list("test_catalog", "custom_db")); - nsRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(nsRequest); - - // Create table in custom database - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog", "custom_db", "custom_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog/custom_db/custom_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: List tables in custom database - ListTablesRequest request = new ListTablesRequest(); - request.setId(Lists.list("test_catalog", "custom_db")); - - ListTablesResponse response = namespace.listTables(request); - - assertEquals(1, response.getTables().size()); - assertTrue(response.getTables().contains("custom_table")); - } - @Test public void testListTablesNonExistentDatabase() { // Test: List tables in non-existent database @@ -613,12 +292,12 @@ public void testDropNamespaceBasicDatabase() throws IOException { // Setup: Create catalog and database CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); catalogRequest.setId(Lists.list("test_catalog_basic_db")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + catalogRequest.setMode("Create"); namespace.createNamespace(catalogRequest); CreateNamespaceRequest dbRequest = new CreateNamespaceRequest(); dbRequest.setId(Lists.list("test_catalog_basic_db", "test_db")); - dbRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + dbRequest.setMode("Create"); Map properties = Maps.newHashMap(); properties.put("database.description", "Test database for dropping"); @@ -652,7 +331,7 @@ public void testDropNamespaceBasicCatalog() { // Setup: Create catalog CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); catalogRequest.setId(Lists.list("test_catalog_basic")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + catalogRequest.setMode("Create"); Map properties = Maps.newHashMap(); properties.put("description", "Test catalog for dropping"); @@ -663,7 +342,7 @@ public void testDropNamespaceBasicCatalog() { // Test: Drop the catalog with CASCADE (since Hive creates default database automatically) DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("test_catalog_basic")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); DropNamespaceResponse response = namespace.dropNamespace(dropRequest); @@ -684,7 +363,7 @@ public void testDropNamespaceSkipMode() { // Test: Drop non-existent database with SKIP mode DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("non_existent_catalog", "non_existent_db")); - dropRequest.setMode(DropNamespaceRequest.ModeEnum.SKIP); + dropRequest.setMode("Skip"); DropNamespaceResponse response = namespace.dropNamespace(dropRequest); @@ -697,151 +376,34 @@ public void testDropNamespaceFailMode() { // Test: Drop non-existent database with FAIL mode (default) DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("non_existent_catalog", "non_existent_db")); - dropRequest.setMode(DropNamespaceRequest.ModeEnum.FAIL); + dropRequest.setMode("Fail"); Exception error = assertThrows(LanceNamespaceException.class, () -> namespace.dropNamespace(dropRequest)); assertTrue(error.getMessage().contains("doesn't exist")); } - @Test - public void testDropDatabaseRestrictWithTables() throws IOException { - // Setup: Create catalog, database and table - CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); - catalogRequest.setId(Lists.list("test_catalog_restrict")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(catalogRequest); - - CreateNamespaceRequest dbRequest = new CreateNamespaceRequest(); - dbRequest.setId(Lists.list("test_catalog_restrict", "test_db")); - dbRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(dbRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog_restrict", "test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog_restrict/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Try to drop database with RESTRICT behavior (should fail) - DropNamespaceRequest dropRequest = new DropNamespaceRequest(); - dropRequest.setId(Lists.list("test_catalog_restrict", "test_db")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.RESTRICT); - - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.dropNamespace(dropRequest)); - assertTrue(error.getMessage().contains("Database test_catalog_restrict.test_db is not empty")); - assertTrue(error.getMessage().contains("Contains 1 tables")); - } - @Test public void testDropCatalogRestrictWithDatabases() { // Setup: Create catalog and database CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); catalogRequest.setId(Lists.list("test_catalog_restrict_db")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + catalogRequest.setMode("Create"); namespace.createNamespace(catalogRequest); CreateNamespaceRequest dbRequest = new CreateNamespaceRequest(); dbRequest.setId(Lists.list("test_catalog_restrict_db", "test_db")); - dbRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); + dbRequest.setMode("Create"); namespace.createNamespace(dbRequest); // Test: Try to drop catalog with RESTRICT behavior (should fail) DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("test_catalog_restrict_db")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.RESTRICT); + dropRequest.setBehavior("Restrict"); Exception error = assertThrows(LanceNamespaceException.class, () -> namespace.dropNamespace(dropRequest)); assertTrue(error.getMessage().contains("is not empty")); assertTrue(error.getMessage().contains("databases")); } - - @Test - public void testDropDatabaseCascadeWithTables() throws IOException { - // Setup: Create catalog, database and multiple tables - CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); - catalogRequest.setId(Lists.list("test_catalog_cascade_db")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(catalogRequest); - - CreateNamespaceRequest dbRequest = new CreateNamespaceRequest(); - dbRequest.setId(Lists.list("test_catalog_cascade_db", "test_db")); - dbRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(dbRequest); - - // Create first table - CreateTableRequest createRequest1 = new CreateTableRequest(); - createRequest1.setId(Lists.list("test_catalog_cascade_db", "test_db", "table1")); - createRequest1.setLocation(tmpDirBase + "/test_catalog_cascade_db/test_db/table1.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest1, testData); - - // Create second table - CreateTableRequest createRequest2 = new CreateTableRequest(); - createRequest2.setId(Lists.list("test_catalog_cascade_db", "test_db", "table2")); - createRequest2.setLocation(tmpDirBase + "/test_catalog_cascade_db/test_db/table2.lance"); - - namespace.createTable(createRequest2, testData); - - // Test: Drop database with CASCADE behavior - DropNamespaceRequest dropRequest = new DropNamespaceRequest(); - dropRequest.setId(Lists.list("test_catalog_cascade_db", "test_db")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); - - DropNamespaceResponse response = namespace.dropNamespace(dropRequest); - - // Verify database properties were returned - assertTrue(response.getProperties().containsKey("database.location-uri")); - - // Verify database was dropped - NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); - existsRequest.setId(Lists.list("test_catalog_cascade_db", "test_db")); - - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.namespaceExists(existsRequest)); - assertTrue(error.getMessage().contains("Namespace does not exist")); - } - - @Test - public void testDropCatalogCascadeWithDatabasesAndTables() throws IOException { - // Setup: Create catalog, database and table - CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); - catalogRequest.setId(Lists.list("test_catalog_cascade")); - catalogRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(catalogRequest); - - CreateNamespaceRequest dbRequest = new CreateNamespaceRequest(); - dbRequest.setId(Lists.list("test_catalog_cascade", "test_db")); - dbRequest.setMode(CreateNamespaceRequest.ModeEnum.CREATE); - namespace.createNamespace(dbRequest); - - CreateTableRequest createRequest = new CreateTableRequest(); - createRequest.setId(Lists.list("test_catalog_cascade", "test_db", "test_table")); - createRequest.setLocation(tmpDirBase + "/test_catalog_cascade/test_db/test_table.lance"); - - byte[] testData = TestHelper.createTestArrowData(allocator); - namespace.createTable(createRequest, testData); - - // Test: Drop catalog with CASCADE behavior - DropNamespaceRequest dropRequest = new DropNamespaceRequest(); - dropRequest.setId(Lists.list("test_catalog_cascade")); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); - - DropNamespaceResponse response = namespace.dropNamespace(dropRequest); - - // Verify catalog properties were returned - assertTrue(response.getProperties().containsKey("catalog.location.uri")); - - // Verify catalog was dropped - NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); - existsRequest.setId(Lists.list("test_catalog_cascade")); - - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.namespaceExists(existsRequest)); - assertTrue(error.getMessage().contains("Namespace does not exist")); - } } diff --git a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java index 457f466..0d04c2d 100644 --- a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java +++ b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java @@ -13,7 +13,7 @@ */ package org.lance.namespace.hive3; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; @@ -110,19 +110,13 @@ public void tearDown() { // Clean up test database DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(testCatalog, testDatabase)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors } - if (namespace != null) { - try { - namespace.close(); - } catch (Exception e) { - // Ignore - } - } + // Namespace cleanup handled by Hive internals if (allocator != null) { allocator.close(); @@ -157,8 +151,8 @@ public void testDatabaseOperations() { DescribeNamespaceResponse describeResponse = namespace.describeNamespace(describeRequest); assertThat(describeResponse).isNotNull(); - assertThat(describeResponse.getProperties()).containsEntry( - "database.description", "Integration test database"); + assertThat(describeResponse.getProperties()) + .containsEntry("database.description", "Integration test database"); // List databases in catalog ListNamespacesRequest listRequest = new ListNamespacesRequest(); @@ -184,7 +178,8 @@ public void testTableOperations() { nsRequest.setId(Arrays.asList(testCatalog, testDatabase)); namespace.createNamespace(nsRequest); - String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); + String tableName = + "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); // Create empty table (declare table without data) CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); @@ -200,7 +195,6 @@ public void testTableOperations() { DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); assertThat(describeResponse.getLocation()).contains(tableName); - assertThat(describeResponse.getProperties()).containsEntry("table_type", "lance"); // List tables ListTablesRequest listRequest = new ListTablesRequest(); @@ -236,7 +230,7 @@ public void testCascadeDropDatabase() { // Drop database with cascade DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(testCatalog, testDatabase)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); // Verify database doesn't exist diff --git a/java/lance-namespace-iceberg/pom.xml b/java/lance-namespace-iceberg/pom.xml index b486c54..b3d2eb5 100644 --- a/java/lance-namespace-iceberg/pom.xml +++ b/java/lance-namespace-iceberg/pom.xml @@ -18,10 +18,18 @@ Iceberg REST Catalog namespace implementation for Lance + + org.lance + lance-namespace-impls-core + org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java index 4db65a3..4754fc2 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java @@ -429,7 +429,7 @@ public static IcebergSchema createDummySchema() { dummyField.setRequired(false); dummyField.setType("string"); - schema.setFields(List.of(dummyField)); + schema.setFields(java.util.Collections.singletonList(dummyField)); return schema; } } diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java index f683f4a..4661d69 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java @@ -14,20 +14,24 @@ package org.lance.namespace.iceberg; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.ObjectIdentifier; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -35,15 +39,17 @@ import org.lance.namespace.model.NamespaceExistsRequest; import org.lance.namespace.model.TableExistsRequest; import org.lance.namespace.rest.RestClient; +import org.lance.namespace.rest.RestClientException; +import org.lance.namespace.util.ObjectIdentifier; import org.lance.namespace.util.ValidationUtil; import org.apache.arrow.memory.BufferAllocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Closeable; import java.io.IOException; import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -51,10 +57,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** Iceberg REST Catalog namespace implementation for Lance. */ -public class IcebergNamespace implements LanceNamespace { +public class IcebergNamespace implements LanceNamespace, Closeable { private static final Logger LOG = LoggerFactory.getLogger(IcebergNamespace.class); private static final String TABLE_TYPE_LANCE = "lance"; private static final String TABLE_TYPE_KEY = "table_type"; @@ -74,19 +81,15 @@ public void initialize(Map configProperties, BufferAllocator all RestClient.Builder clientBuilder = RestClient.builder() .baseUrl(config.getFullApiUrl()) - .connectTimeout(config.getConnectTimeout()) - .readTimeout(config.getReadTimeout()) + .connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS) + .readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS) .maxRetries(config.getMaxRetries()); - Map headers = new HashMap<>(); if (config.getAuthToken() != null) { - headers.put("Authorization", "Bearer " + config.getAuthToken()); + clientBuilder.authToken(config.getAuthToken()); } if (config.getWarehouse() != null) { - headers.put("X-Iceberg-Access-Delegation", "vended-credentials"); - } - if (!headers.isEmpty()) { - clientBuilder.defaultHeaders(headers); + clientBuilder.header("X-Iceberg-Access-Delegation", "vended-credentials"); } this.restClient = clientBuilder.build(); @@ -100,12 +103,15 @@ public String namespaceId() { @Override public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { - ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); + ObjectIdentifier nsId = + request.getId() != null + ? ObjectIdentifier.of(request.getId()) + : ObjectIdentifier.of(Collections.emptyList()); try { Map params = new HashMap<>(); if (nsId.levels() > 0) { - String parent = encodeNamespace(nsId.getIdentifier()); + String parent = encodeNamespace(nsId.listStyleId()); params.put("parent", parent); } if (request.getPageToken() != null) { @@ -113,7 +119,9 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { } IcebergModels.ListNamespacesResponse response = - restClient.get("/namespaces", params, IcebergModels.ListNamespacesResponse.class); + params.isEmpty() + ? restClient.get("/namespaces", IcebergModels.ListNamespacesResponse.class) + : restClient.get("/namespaces", params, IcebergModels.ListNamespacesResponse.class); List namespaces = new ArrayList<>(); if (response != null && response.getNamespaces() != null) { @@ -130,9 +138,8 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ListNamespacesResponse result = new ListNamespacesResponse(); result.setNamespaces(resultNamespaces); return result; - - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to list namespaces: " + e.getMessage()); + } catch (RestClientException e) { + throw new InternalException("Failed to list namespaces: " + e.getMessage()); } } @@ -144,27 +151,24 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { try { IcebergModels.CreateNamespaceRequest createRequest = new IcebergModels.CreateNamespaceRequest(); - createRequest.setNamespace(nsId.getIdentifier()); + createRequest.setNamespace(nsId.listStyleId()); createRequest.setProperties(request.getProperties()); IcebergModels.CreateNamespaceResponse response = - restClient.post("/namespaces", createRequest, IcebergModels.CreateNamespaceResponse.class); + restClient.post( + "/namespaces", createRequest, IcebergModels.CreateNamespaceResponse.class); + + LOG.info("Created namespace: {}", nsId.stringStyleId()); CreateNamespaceResponse result = new CreateNamespaceResponse(); result.setProperties(response != null ? response.getProperties() : null); return result; - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Namespace already exists", - "NAMESPACE_EXISTS", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new NamespaceAlreadyExistsException( + "Namespace already exists: " + nsId.stringStyleId()); } - throw new LanceNamespaceException(500, "Failed to create namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to create namespace: " + e.getMessage()); + throw new InternalException("Failed to create namespace: " + e.getMessage()); } } @@ -174,25 +178,18 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); try { - String namespacePath = encodeNamespace(nsId.getIdentifier()); + String namespacePath = encodeNamespace(nsId.listStyleId()); IcebergModels.GetNamespaceResponse response = restClient.get("/namespaces/" + namespacePath, IcebergModels.GetNamespaceResponse.class); DescribeNamespaceResponse result = new DescribeNamespaceResponse(); result.setProperties(response != null ? response.getProperties() : null); return result; - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + nsId.stringStyleId()); } - throw new LanceNamespaceException(500, "Failed to describe namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to describe namespace: " + e.getMessage()); + throw new InternalException("Failed to describe namespace: " + e.getMessage()); } } @@ -207,25 +204,15 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); try { - String namespacePath = encodeNamespace(nsId.getIdentifier()); + String namespacePath = encodeNamespace(nsId.listStyleId()); restClient.delete("/namespaces/" + namespacePath); - + LOG.info("Dropped namespace: {}", nsId.stringStyleId()); return new DropNamespaceResponse(); - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { + } catch (RestClientException e) { + if (e.isNotFound()) { return new DropNamespaceResponse(); } - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Namespace not empty", - "NAMESPACE_NOT_EMPTY", - request.getId().toString(), - e.getResponseBody()); - } - throw new LanceNamespaceException(500, "Failed to drop namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to drop namespace: " + e.getMessage()); + throw new InternalException("Failed to drop namespace: " + e.getMessage()); } } @@ -235,22 +222,26 @@ public ListTablesResponse listTables(ListTablesRequest request) { ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); try { - String namespacePath = encodeNamespace(nsId.getIdentifier()); + String namespacePath = encodeNamespace(nsId.listStyleId()); Map params = new HashMap<>(); if (request.getPageToken() != null) { params.put("pageToken", request.getPageToken()); } IcebergModels.ListTablesResponse response = - restClient.get( - "/namespaces/" + namespacePath + "/tables", - params, - IcebergModels.ListTablesResponse.class); + params.isEmpty() + ? restClient.get( + "/namespaces/" + namespacePath + "/tables", + IcebergModels.ListTablesResponse.class) + : restClient.get( + "/namespaces/" + namespacePath + "/tables", + params, + IcebergModels.ListTablesResponse.class); List tables = new ArrayList<>(); if (response != null && response.getIdentifiers() != null) { for (IcebergModels.TableIdentifier tableId : response.getIdentifiers()) { - if (isLanceTable(nsId.getIdentifier(), tableId.getName())) { + if (isLanceTable(nsId.listStyleId(), tableId.getName())) { tables.add(tableId.getName()); } } @@ -262,9 +253,11 @@ public ListTablesResponse listTables(ListTablesRequest request) { ListTablesResponse result = new ListTablesResponse(); result.setTables(resultTables); return result; - - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to list tables: " + e.getMessage()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + nsId.stringStyleId()); + } + throw new InternalException("Failed to list tables: " + e.getMessage()); } } @@ -274,7 +267,7 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request ValidationUtil.checkArgument( tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); - List namespace = tableId.getIdentifier().subList(0, tableId.levels() - 1); + List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { @@ -290,9 +283,6 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request Map properties = new HashMap<>(); properties.put(TABLE_TYPE_KEY, TABLE_TYPE_LANCE); - if (request.getProperties() != null) { - properties.putAll(request.getProperties()); - } createRequest.setProperties(properties); String namespacePath = encodeNamespace(namespace); @@ -302,31 +292,19 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request createRequest, IcebergModels.LoadTableResponse.class); + LOG.info("Created Lance table: {}.{}", namespacePath, tableName); + CreateEmptyTableResponse result = new CreateEmptyTableResponse(); result.setLocation(tablePath); - if (response != null && response.getMetadata() != null) { - result.setProperties(response.getMetadata().getProperties()); - } return result; - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new TableAlreadyExistsException("Table already exists: " + tableId.stringStyleId()); } - if (e.getStatusCode() == 404) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - String.join(".", namespace), - e.getResponseBody()); + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + String.join(".", namespace)); } - throw new LanceNamespaceException(500, "Failed to create empty table: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to create empty table: " + e.getMessage()); + throw new InternalException("Failed to create table: " + e.getMessage()); } } @@ -336,12 +314,12 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { ValidationUtil.checkArgument( tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); - List namespace = tableId.getIdentifier().subList(0, tableId.levels() - 1); + List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { String namespacePath = encodeNamespace(namespace); - String encodedTableName = URLEncoder.encode(tableName, StandardCharsets.UTF_8); + String encodedTableName = urlEncode(tableName); IcebergModels.LoadTableResponse response = restClient.get( @@ -349,32 +327,26 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { IcebergModels.LoadTableResponse.class); if (response == null || response.getMetadata() == null) { - throw LanceNamespaceException.notFound( - "Table not found", "TABLE_NOT_FOUND", request.getId().toString(), "No metadata"); + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); } Map props = response.getMetadata().getProperties(); if (props == null || !TABLE_TYPE_LANCE.equalsIgnoreCase(props.get(TABLE_TYPE_KEY))) { - throw LanceNamespaceException.badRequest( - "Not a Lance table", - "INVALID_TABLE", - request.getId().toString(), - "Table is not managed by Lance"); + throw new InvalidInputException( + String.format( + "Table %s is not a Lance table (missing table_type property)", + tableId.stringStyleId())); } DescribeTableResponse result = new DescribeTableResponse(); result.setLocation(response.getMetadata().getLocation()); - result.setProperties(props); + result.setStorageOptions(props); return result; - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - throw LanceNamespaceException.notFound( - "Table not found", "TABLE_NOT_FOUND", request.getId().toString(), e.getResponseBody()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); } - throw new LanceNamespaceException(500, "Failed to describe table: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to describe table: " + e.getMessage()); + throw new InternalException("Failed to describe table: " + e.getMessage()); } } @@ -384,49 +356,43 @@ public void tableExists(TableExistsRequest request) { } @Override - public DropTableResponse dropTable(DropTableRequest request) { + public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); - List namespace = tableId.getIdentifier().subList(0, tableId.levels() - 1); + List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { String namespacePath = encodeNamespace(namespace); - String encodedTableName = URLEncoder.encode(tableName, StandardCharsets.UTF_8); - - String tableLocation = null; - try { - IcebergModels.LoadTableResponse tableResponse = - restClient.get( - "/namespaces/" + namespacePath + "/tables/" + encodedTableName, - IcebergModels.LoadTableResponse.class); - if (tableResponse != null && tableResponse.getMetadata() != null) { - tableLocation = tableResponse.getMetadata().getLocation(); - } - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - DropTableResponse result = new DropTableResponse(); - result.setId(request.getId()); - return result; - } + String encodedTableName = urlEncode(tableName); + + IcebergModels.LoadTableResponse getResponse = + restClient.get( + "/namespaces/" + namespacePath + "/tables/" + encodedTableName, + IcebergModels.LoadTableResponse.class); + + String location = null; + if (getResponse != null && getResponse.getMetadata() != null) { + location = getResponse.getMetadata().getLocation(); } - Map params = new HashMap<>(); - params.put("purgeRequested", "false"); - restClient.delete("/namespaces/" + namespacePath + "/tables/" + encodedTableName, params); + restClient.delete("/namespaces/" + namespacePath + "/tables/" + encodedTableName); + LOG.info("Deregistered table: {}.{}", namespacePath, tableName); - DropTableResponse result = new DropTableResponse(); - result.setId(request.getId()); - result.setLocation(tableLocation); + DeregisterTableResponse result = new DeregisterTableResponse(); + result.setLocation(location); return result; - - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to drop table: " + e.getMessage()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); + } + throw new InternalException("Failed to deregister table: " + e.getMessage()); } } + @Override public void close() throws IOException { if (restClient != null) { restClient.close(); @@ -436,15 +402,23 @@ public void close() throws IOException { private String encodeNamespace(List namespace) { String joined = namespace.stream() - .map(s -> URLEncoder.encode(s, StandardCharsets.UTF_8)) + .map(this::urlEncode) .collect(Collectors.joining(String.valueOf(NAMESPACE_SEPARATOR))); - return URLEncoder.encode(joined, StandardCharsets.UTF_8); + return urlEncode(joined); + } + + private String urlEncode(String s) { + try { + return URLEncoder.encode(s, "UTF-8"); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 encoding not supported", e); + } } private boolean isLanceTable(List namespace, String tableName) { try { String namespacePath = encodeNamespace(namespace); - String encodedTableName = URLEncoder.encode(tableName, StandardCharsets.UTF_8); + String encodedTableName = urlEncode(tableName); IcebergModels.LoadTableResponse response = restClient.get( diff --git a/java/lance-namespace-impls-core/pom.xml b/java/lance-namespace-impls-core/pom.xml new file mode 100644 index 0000000..878d8c3 --- /dev/null +++ b/java/lance-namespace-impls-core/pom.xml @@ -0,0 +1,97 @@ + + + 4.0.0 + + + org.lance + lance-namespace-impls-root + 0.0.1 + + + lance-namespace-impls-core + ${project.artifactId} + Core utilities for Lance Namespace implementations including RestClient + + + + + org.lance + lance-namespace-core + + + + + org.apache.httpcomponents.client5 + httpclient5 + 5.2.1 + + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + org.slf4j + slf4j-api + + + + + org.apache.arrow + arrow-vector + + + org.apache.arrow + arrow-memory-netty + + + + + org.junit.jupiter + junit-jupiter + test + + + org.mockito + mockito-core + test + + + org.mockito + mockito-junit-jupiter + test + + + org.assertj + assertj-core + test + + + org.slf4j + slf4j-simple + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + diff --git a/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClient.java b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClient.java new file mode 100644 index 0000000..d92cbed --- /dev/null +++ b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClient.java @@ -0,0 +1,412 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.rest; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPatch; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.util.Timeout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * A reusable REST client for making HTTP requests to REST APIs. + * + *

This client provides: + * + *

    + *
  • Connection pooling for efficient HTTP connections + *
  • Configurable timeouts for connect and read operations + *
  • Retry logic with exponential backoff + *
  • JSON serialization/deserialization via Jackson + *
  • Support for common HTTP methods (GET, POST, PUT, PATCH, DELETE) + *
+ * + *

Example usage: + * + *

{@code
+ * RestClient client = RestClient.builder()
+ *     .baseUrl("http://localhost:8080/api")
+ *     .header("Authorization", "Bearer token")
+ *     .connectTimeout(10, TimeUnit.SECONDS)
+ *     .readTimeout(30, TimeUnit.SECONDS)
+ *     .maxRetries(3)
+ *     .build();
+ *
+ * MyResponse response = client.get("/resource", MyResponse.class);
+ * }
+ */ +public class RestClient implements Closeable { + private static final Logger LOG = LoggerFactory.getLogger(RestClient.class); + + private static final int DEFAULT_MAX_CONNECTIONS = 20; + private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 10; + private static final int DEFAULT_CONNECT_TIMEOUT_MS = 10000; + private static final int DEFAULT_READ_TIMEOUT_MS = 30000; + private static final int DEFAULT_MAX_RETRIES = 3; + private static final long DEFAULT_RETRY_DELAY_MS = 1000; + + private final String baseUrl; + private final Map defaultHeaders; + private final CloseableHttpClient httpClient; + private final ObjectMapper objectMapper; + private final int maxRetries; + private final long retryDelayMs; + + private RestClient(Builder builder) { + this.baseUrl = + builder.baseUrl.endsWith("/") + ? builder.baseUrl.substring(0, builder.baseUrl.length() - 1) + : builder.baseUrl; + this.defaultHeaders = new HashMap<>(builder.defaultHeaders); + this.maxRetries = builder.maxRetries; + this.retryDelayMs = builder.retryDelayMs; + + this.objectMapper = + builder.objectMapper != null + ? builder.objectMapper + : new ObjectMapper() + .registerModule(new JavaTimeModule()) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(builder.maxConnections); + connectionManager.setDefaultMaxPerRoute(builder.maxConnectionsPerRoute); + + RequestConfig requestConfig = + RequestConfig.custom() + .setConnectTimeout(Timeout.ofMilliseconds(builder.connectTimeoutMs)) + .setResponseTimeout(Timeout.ofMilliseconds(builder.readTimeoutMs)) + .build(); + + this.httpClient = + HttpClients.custom() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(requestConfig) + .build(); + } + + public static Builder builder() { + return new Builder(); + } + + public String getBaseUrl() { + return baseUrl; + } + + public T get(String path, Class responseType) throws RestClientException { + return execute(new HttpGet(buildUri(path)), null, responseType); + } + + public T get(String path, Map queryParams, Class responseType) + throws RestClientException { + HttpGet request = new HttpGet(buildUri(path, queryParams)); + return execute(request, null, responseType); + } + + public T getWithHeaders(String path, Map headers, Class responseType) + throws RestClientException { + HttpGet request = new HttpGet(buildUri(path)); + headers.forEach(request::addHeader); + return execute(request, null, responseType); + } + + public T get( + String path, + Map queryParams, + Map headers, + Class responseType) + throws RestClientException { + HttpGet request = new HttpGet(buildUri(path, queryParams)); + headers.forEach(request::addHeader); + return execute(request, null, responseType); + } + + public T post(String path, Object body, Class responseType) throws RestClientException { + HttpPost request = new HttpPost(buildUri(path)); + return execute(request, body, responseType); + } + + public T post(String path, Object body, Map headers, Class responseType) + throws RestClientException { + HttpPost request = new HttpPost(buildUri(path)); + headers.forEach(request::addHeader); + return execute(request, body, responseType); + } + + public T put(String path, Object body, Class responseType) throws RestClientException { + HttpPut request = new HttpPut(buildUri(path)); + return execute(request, body, responseType); + } + + public T put(String path, Object body, Map headers, Class responseType) + throws RestClientException { + HttpPut request = new HttpPut(buildUri(path)); + headers.forEach(request::addHeader); + return execute(request, body, responseType); + } + + public T patch(String path, Object body, Class responseType) throws RestClientException { + HttpPatch request = new HttpPatch(buildUri(path)); + return execute(request, body, responseType); + } + + public void delete(String path) throws RestClientException { + execute(new HttpDelete(buildUri(path)), null, Void.class); + } + + public void delete(String path, Map headers) throws RestClientException { + HttpDelete request = new HttpDelete(buildUri(path)); + headers.forEach(request::addHeader); + execute(request, null, Void.class); + } + + public T delete(String path, Class responseType) throws RestClientException { + return execute(new HttpDelete(buildUri(path)), null, responseType); + } + + private URI buildUri(String path) { + String fullPath = path.startsWith("/") ? baseUrl + path : baseUrl + "/" + path; + return URI.create(fullPath); + } + + private URI buildUri(String path, Map queryParams) { + String fullPath = path.startsWith("/") ? baseUrl + path : baseUrl + "/" + path; + if (queryParams != null && !queryParams.isEmpty()) { + StringBuilder sb = new StringBuilder(fullPath); + sb.append("?"); + boolean first = true; + for (Map.Entry entry : queryParams.entrySet()) { + if (!first) { + sb.append("&"); + } + try { + sb.append(java.net.URLEncoder.encode(entry.getKey(), "UTF-8")); + sb.append("="); + sb.append(java.net.URLEncoder.encode(entry.getValue(), "UTF-8")); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 encoding not supported", e); + } + first = false; + } + fullPath = sb.toString(); + } + return URI.create(fullPath); + } + + private T execute(HttpUriRequestBase request, Object body, Class responseType) + throws RestClientException { + defaultHeaders.forEach(request::addHeader); + + if (body != null) { + try { + String jsonBody = objectMapper.writeValueAsString(body); + request.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON)); + } catch (JsonProcessingException e) { + throw new RestClientException(-1, "Failed to serialize request body", e); + } + } + + int attempt = 0; + RestClientException lastException = null; + + while (attempt <= maxRetries) { + try { + return httpClient.execute( + request, + response -> { + int statusCode = response.getCode(); + String responseBody = + response.getEntity() != null ? EntityUtils.toString(response.getEntity()) : null; + + if (statusCode >= 200 && statusCode < 300) { + if (responseType == Void.class || responseBody == null || responseBody.isEmpty()) { + return null; + } + try { + return objectMapper.readValue(responseBody, responseType); + } catch (JsonProcessingException e) { + throw new RestClientException( + statusCode, "Failed to deserialize response: " + responseBody, e); + } + } else { + throw new RestClientException(statusCode, responseBody); + } + }); + } catch (RestClientException e) { + lastException = e; + if (e.getStatusCode() >= 400 && e.getStatusCode() < 500) { + throw e; + } + attempt++; + if (attempt <= maxRetries) { + long delay = retryDelayMs * (1L << (attempt - 1)); + LOG.warn( + "Request failed with status {}, retrying in {}ms (attempt {}/{})", + e.getStatusCode(), + delay, + attempt, + maxRetries); + try { + Thread.sleep(delay); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw new RestClientException(-1, "Interrupted during retry", ie); + } + } + } catch (IOException e) { + lastException = new RestClientException(-1, "IO error: " + e.getMessage(), e); + attempt++; + if (attempt <= maxRetries) { + long delay = retryDelayMs * (1L << (attempt - 1)); + LOG.warn( + "Request failed with IO error, retrying in {}ms (attempt {}/{})", + delay, + attempt, + maxRetries); + try { + Thread.sleep(delay); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw new RestClientException(-1, "Interrupted during retry", ie); + } + } + } + } + + throw lastException != null + ? lastException + : new RestClientException(-1, "Unknown error after retries"); + } + + @Override + public void close() throws IOException { + if (httpClient != null) { + httpClient.close(); + } + } + + public static class Builder { + private String baseUrl; + private final Map defaultHeaders = new HashMap<>(); + private int maxConnections = DEFAULT_MAX_CONNECTIONS; + private int maxConnectionsPerRoute = DEFAULT_MAX_CONNECTIONS_PER_ROUTE; + private int connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS; + private int readTimeoutMs = DEFAULT_READ_TIMEOUT_MS; + private int maxRetries = DEFAULT_MAX_RETRIES; + private long retryDelayMs = DEFAULT_RETRY_DELAY_MS; + private ObjectMapper objectMapper; + + public Builder baseUrl(String baseUrl) { + this.baseUrl = Objects.requireNonNull(baseUrl, "baseUrl cannot be null"); + return this; + } + + public Builder header(String name, String value) { + this.defaultHeaders.put(name, value); + return this; + } + + public Builder headers(Map headers) { + this.defaultHeaders.putAll(headers); + return this; + } + + public Builder authToken(String token) { + if (token != null && !token.isEmpty()) { + this.defaultHeaders.put("Authorization", "Bearer " + token); + } + return this; + } + + public Builder maxConnections(int maxConnections) { + this.maxConnections = maxConnections; + return this; + } + + public Builder maxConnectionsPerRoute(int maxConnectionsPerRoute) { + this.maxConnectionsPerRoute = maxConnectionsPerRoute; + return this; + } + + public Builder connectTimeout(int timeout, TimeUnit unit) { + this.connectTimeoutMs = (int) unit.toMillis(timeout); + return this; + } + + public Builder connectTimeoutMs(int connectTimeoutMs) { + this.connectTimeoutMs = connectTimeoutMs; + return this; + } + + public Builder readTimeout(int timeout, TimeUnit unit) { + this.readTimeoutMs = (int) unit.toMillis(timeout); + return this; + } + + public Builder readTimeoutMs(int readTimeoutMs) { + this.readTimeoutMs = readTimeoutMs; + return this; + } + + public Builder maxRetries(int maxRetries) { + this.maxRetries = maxRetries; + return this; + } + + public Builder retryDelay(long delay, TimeUnit unit) { + this.retryDelayMs = unit.toMillis(delay); + return this; + } + + public Builder retryDelayMs(long retryDelayMs) { + this.retryDelayMs = retryDelayMs; + return this; + } + + public Builder objectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + return this; + } + + public RestClient build() { + Objects.requireNonNull(baseUrl, "baseUrl is required"); + return new RestClient(this); + } + } +} diff --git a/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClientException.java b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClientException.java new file mode 100644 index 0000000..b976b1d --- /dev/null +++ b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/rest/RestClientException.java @@ -0,0 +1,72 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.rest; + +/** + * Exception thrown when a REST API call fails. + * + *

Contains the HTTP status code and response body for error diagnosis. + */ +public class RestClientException extends RuntimeException { + private final int statusCode; + private final String responseBody; + + public RestClientException(int statusCode, String responseBody) { + super(String.format("HTTP %d: %s", statusCode, responseBody)); + this.statusCode = statusCode; + this.responseBody = responseBody; + } + + public RestClientException(int statusCode, String message, Throwable cause) { + super(String.format("HTTP %d: %s", statusCode, message), cause); + this.statusCode = statusCode; + this.responseBody = message; + } + + public int getStatusCode() { + return statusCode; + } + + public String getResponseBody() { + return responseBody; + } + + public boolean isClientError() { + return statusCode >= 400 && statusCode < 500; + } + + public boolean isServerError() { + return statusCode >= 500; + } + + public boolean isNotFound() { + return statusCode == 404; + } + + public boolean isConflict() { + return statusCode == 409; + } + + public boolean isBadRequest() { + return statusCode == 400; + } + + public boolean isUnauthorized() { + return statusCode == 401; + } + + public boolean isForbidden() { + return statusCode == 403; + } +} diff --git a/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/test/TestHelper.java b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/test/TestHelper.java new file mode 100644 index 0000000..e4e7d75 --- /dev/null +++ b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/test/TestHelper.java @@ -0,0 +1,78 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.test; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.arrow.vector.ipc.ArrowStreamWriter; +import org.apache.arrow.vector.types.pojo.ArrowType; +import org.apache.arrow.vector.types.pojo.Field; +import org.apache.arrow.vector.types.pojo.Schema; + +import java.io.ByteArrayOutputStream; +import java.nio.channels.Channels; +import java.util.Arrays; + +/** Test utilities for creating Arrow IPC data. */ +public final class TestHelper { + + private TestHelper() {} + + /** + * Creates test Arrow IPC data with a simple schema (id: int32, name: utf8). + * + * @param allocator Arrow buffer allocator + * @return Arrow IPC stream bytes + */ + public static byte[] createTestArrowData(BufferAllocator allocator) { + Schema schema = + new Schema( + Arrays.asList( + Field.nullable("id", new ArrowType.Int(32, true)), + Field.nullable("name", ArrowType.Utf8.INSTANCE))); + + return createArrowIpcStream(allocator, schema); + } + + /** + * Creates empty Arrow IPC data with a simple schema. + * + * @param allocator Arrow buffer allocator + * @return Arrow IPC stream bytes + */ + public static byte[] createEmptyArrowData(BufferAllocator allocator) { + return createTestArrowData(allocator); + } + + /** + * Creates Arrow IPC stream bytes from a schema. + * + * @param allocator Arrow buffer allocator + * @param schema Arrow schema + * @return Arrow IPC stream bytes + */ + public static byte[] createArrowIpcStream(BufferAllocator allocator, Schema schema) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (VectorSchemaRoot root = VectorSchemaRoot.create(schema, allocator); + ArrowStreamWriter writer = new ArrowStreamWriter(root, null, Channels.newChannel(out))) { + writer.start(); + writer.end(); + } + return out.toByteArray(); + } catch (Exception e) { + throw new RuntimeException("Failed to create Arrow IPC stream", e); + } + } +} diff --git a/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ObjectIdentifier.java b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ObjectIdentifier.java new file mode 100644 index 0000000..6945fbd --- /dev/null +++ b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ObjectIdentifier.java @@ -0,0 +1,140 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * Represents a hierarchical object identifier (namespace or table). + * + *

An identifier consists of one or more levels, where each level is a string. For example: + * + *

    + *
  • A root identifier has 0 levels + *
  • A catalog identifier has 1 level (e.g., ["my_catalog"]) + *
  • A database identifier has 2 levels (e.g., ["my_catalog", "my_database"]) + *
  • A table identifier has 3 levels (e.g., ["my_catalog", "my_database", "my_table"]) + *
+ */ +public class ObjectIdentifier { + private static final ObjectIdentifier ROOT = new ObjectIdentifier(Collections.emptyList()); + private final List levels; + + private ObjectIdentifier(List levels) { + this.levels = Collections.unmodifiableList(new ArrayList<>(levels)); + } + + public static ObjectIdentifier root() { + return ROOT; + } + + public static ObjectIdentifier of(List levels) { + if (levels == null || levels.isEmpty()) { + return ROOT; + } + return new ObjectIdentifier(levels); + } + + public static ObjectIdentifier of(Set levels) { + if (levels == null || levels.isEmpty()) { + return ROOT; + } + return new ObjectIdentifier(new ArrayList<>(levels)); + } + + public static ObjectIdentifier of(String... levels) { + if (levels == null || levels.length == 0) { + return ROOT; + } + return new ObjectIdentifier(Arrays.asList(levels)); + } + + public boolean isRoot() { + return levels.isEmpty(); + } + + public int levels() { + return levels.size(); + } + + public String levelAtListPos(int index) { + if (index < 0 || index >= levels.size()) { + throw new IndexOutOfBoundsException( + "Index " + index + " out of bounds for identifier with " + levels.size() + " levels"); + } + return levels.get(index); + } + + public List getLevels() { + return levels; + } + + public ObjectIdentifier parent() { + if (isRoot()) { + throw new IllegalStateException("Root identifier has no parent"); + } + return of(levels.subList(0, levels.size() - 1)); + } + + public String name() { + if (isRoot()) { + throw new IllegalStateException("Root identifier has no name"); + } + return levels.get(levels.size() - 1); + } + + public ObjectIdentifier child(String name) { + List newLevels = new ArrayList<>(levels); + newLevels.add(name); + return of(newLevels); + } + + @Override + public String toString() { + if (isRoot()) { + return "[]"; + } + return levels.toString(); + } + + public String toDelimited(String delimiter) { + return String.join(delimiter, levels); + } + + public List listStyleId() { + return levels; + } + + public String stringStyleId() { + return String.join(".", levels); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + ObjectIdentifier that = (ObjectIdentifier) obj; + return Objects.equals(levels, that.levels); + } + + @Override + public int hashCode() { + return Objects.hash(levels); + } +} diff --git a/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ValidationUtil.java b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ValidationUtil.java new file mode 100644 index 0000000..71cd20a --- /dev/null +++ b/java/lance-namespace-impls-core/src/main/java/org/lance/namespace/util/ValidationUtil.java @@ -0,0 +1,46 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.util; + +import org.lance.namespace.errors.InvalidInputException; + +/** Utility methods for validation. */ +public final class ValidationUtil { + + private ValidationUtil() {} + + public static void checkArgument(boolean condition, String message, Object... args) { + if (!condition) { + throw new InvalidInputException(String.format(message, args)); + } + } + + public static void checkNotNull(Object reference, String message, Object... args) { + if (reference == null) { + throw new InvalidInputException(String.format(message, args)); + } + } + + public static void checkNotEmpty(String value, String message, Object... args) { + if (value == null || value.isEmpty()) { + throw new InvalidInputException(String.format(message, args)); + } + } + + public static void checkState(boolean condition, String message, Object... args) { + if (!condition) { + throw new IllegalStateException(String.format(message, args)); + } + } +} diff --git a/java/lance-namespace-polaris/pom.xml b/java/lance-namespace-polaris/pom.xml index 2c0f5cf..cf71b17 100644 --- a/java/lance-namespace-polaris/pom.xml +++ b/java/lance-namespace-polaris/pom.xml @@ -31,10 +31,18 @@ Polaris Catalog implementation for Lance namespace management + + org.lance + lance-namespace-impls-core + org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java index e5ef4f3..5f77297 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java @@ -13,23 +13,25 @@ */ package org.lance.namespace.polaris; -import com.lancedb.lance.Dataset; -import com.lancedb.lance.WriteParams; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.ObjectIdentifier; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -37,13 +39,15 @@ import org.lance.namespace.model.NamespaceExistsRequest; import org.lance.namespace.model.TableExistsRequest; import org.lance.namespace.rest.RestClient; +import org.lance.namespace.rest.RestClientException; +import org.lance.namespace.util.ObjectIdentifier; import org.lance.namespace.util.ValidationUtil; import org.apache.arrow.memory.BufferAllocator; -import org.apache.arrow.vector.types.pojo.Schema; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Closeable; import java.io.IOException; import java.util.Collections; import java.util.HashMap; @@ -51,9 +55,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; /** Polaris Catalog namespace implementation for Lance. */ -public class PolarisNamespace implements LanceNamespace { +public class PolarisNamespace implements LanceNamespace, Closeable { private static final Logger LOG = LoggerFactory.getLogger(PolarisNamespace.class); private static final String TABLE_FORMAT_LANCE = "lance"; private static final String TABLE_TYPE_KEY = "table_type"; @@ -69,19 +74,15 @@ public void initialize(Map configProperties, BufferAllocator all this.allocator = allocator; this.config = new PolarisNamespaceConfig(configProperties); - // Build REST client with authentication if provided RestClient.Builder clientBuilder = RestClient.builder() .baseUrl(config.getFullApiUrl()) - .connectTimeout(config.getConnectTimeout()) - .readTimeout(config.getReadTimeout()) + .connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS) + .readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS) .maxRetries(config.getMaxRetries()); - // Add auth token if provided if (config.getAuthToken() != null) { - Map headers = new HashMap<>(); - headers.put("Authorization", "Bearer " + config.getAuthToken()); - clientBuilder.defaultHeaders(headers); + clientBuilder.authToken(config.getAuthToken()); } this.restClient = clientBuilder.build(); @@ -101,13 +102,11 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { namespaceId.levels() >= 1, "Namespace must have at least one level"); try { - // Convert request to Polaris format List namespace = namespaceId.listStyleId(); PolarisModels.CreateNamespaceRequest polarisRequest = new PolarisModels.CreateNamespaceRequest(namespace, request.getProperties()); - // Create namespace using Iceberg REST API endpoint PolarisModels.NamespaceResponse response = restClient.post("/namespaces", polarisRequest, PolarisModels.NamespaceResponse.class); @@ -116,9 +115,12 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { CreateNamespaceResponse result = new CreateNamespaceResponse(); result.setProperties(response.getProperties()); return result; - } catch (IOException e) { - throw LanceNamespaceException.serverError( - "Failed to create namespace", "ServerError", namespaceId.stringStyleId(), e.getMessage()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new NamespaceAlreadyExistsException( + "Namespace already exists: " + namespaceId.stringStyleId()); + } + throw new InternalException("Failed to create namespace: " + e.getMessage()); } } @@ -131,26 +133,17 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ try { String namespacePath = namespaceId.stringStyleId(); - // Get namespace properties using Iceberg REST API PolarisModels.NamespaceResponse response = restClient.get("/namespaces/" + namespacePath, PolarisModels.NamespaceResponse.class); DescribeNamespaceResponse result = new DescribeNamespaceResponse(); result.setProperties(response.getProperties()); return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NoSuchNamespace", - namespaceId.stringStyleId(), - "Namespace not found: " + namespaceId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + namespaceId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to describe namespace", - "ServerError", - namespaceId.stringStyleId(), - e.getMessage()); + throw new InternalException("Failed to describe namespace: " + e.getMessage()); } } @@ -167,12 +160,10 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { path += "/" + parentId.stringStyleId() + "/namespaces"; } - // List namespaces using Iceberg REST API PolarisModels.ListNamespacesResponse response = restClient.get(path, PolarisModels.ListNamespacesResponse.class); ListNamespacesResponse result = new ListNamespacesResponse(); - // Convert namespace identifiers to Set with full paths Set namespaceSet = new LinkedHashSet<>(); if (response.getNamespaces() != null) { for (PolarisModels.ListNamespacesResponse.Namespace ns : response.getNamespaces()) { @@ -181,9 +172,8 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { } result.setNamespaces(namespaceSet); return result; - } catch (IOException e) { - throw LanceNamespaceException.serverError( - "Failed to list namespaces", "ServerError", "listNamespaces", e.getMessage()); + } catch (RestClientException e) { + throw new InternalException("Failed to list namespaces: " + e.getMessage()); } } @@ -195,25 +185,14 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { try { String namespacePath = namespaceId.stringStyleId(); - - // Drop namespace using Iceberg REST API restClient.delete("/namespaces/" + namespacePath); - LOG.info("Dropped namespace: {}", namespacePath); - - DropNamespaceResponse result = new DropNamespaceResponse(); - // DropNamespaceResponse has no fields to set - return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NoSuchNamespace", - namespaceId.stringStyleId(), - "Namespace not found: " + namespaceId.stringStyleId()); + return new DropNamespaceResponse(); + } catch (RestClientException e) { + if (e.isNotFound()) { + return new DropNamespaceResponse(); } - throw LanceNamespaceException.serverError( - "Failed to drop namespace", "ServerError", namespaceId.stringStyleId(), e.getMessage()); + throw new InternalException("Failed to drop namespace: " + e.getMessage()); } } @@ -225,22 +204,12 @@ public void namespaceExists(NamespaceExistsRequest request) { try { String namespacePath = namespaceId.stringStyleId(); - // Use GET request to check if namespace exists restClient.get("/namespaces/" + namespacePath, PolarisModels.NamespaceResponse.class); - // If we get here, namespace exists - return normally - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NoSuchNamespace", - namespaceId.stringStyleId(), - "Namespace not found: " + namespaceId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + namespaceId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to check namespace existence", - "ServerError", - namespaceId.stringStyleId(), - e.getMessage()); + throw new InternalException("Failed to check namespace existence: " + e.getMessage()); } } @@ -251,30 +220,19 @@ public void tableExists(TableExistsRequest request) { tableId.levels() >= 2, "Table identifier must have at least 2 levels"); try { - // Split into namespace and table name List parts = tableId.listStyleId(); String tableName = parts.get(parts.size() - 1); List namespaceParts = parts.subList(0, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); - // Use GET request to check if table exists restClient.get( "/namespaces/" + namespacePath + "/generic-tables/" + tableName, PolarisModels.LoadGenericTableResponse.class); - // If we get here, table exists - return normally - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Table not found", - "NoSuchTable", - tableId.stringStyleId(), - "Table not found: " + tableId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to check table existence", - "ServerError", - tableId.stringStyleId(), - e.getMessage()); + throw new InternalException("Failed to check table existence: " + e.getMessage()); } } @@ -285,34 +243,19 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request tableId.levels() >= 2, "Table identifier must have at least 2 levels"); try { - // Split into namespace and table name List parts = tableId.listStyleId(); String tableName = parts.get(parts.size() - 1); List namespaceParts = parts.subList(0, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); - // Prepare table properties Map properties = new HashMap<>(); - String comment = null; - if (request.getProperties() != null) { - properties.putAll(request.getProperties()); - // Extract comment to use as doc field - comment = properties.remove("comment"); - } - - // Add Lance-specific properties properties.put(TABLE_TYPE_KEY, TABLE_FORMAT_LANCE); + String comment = null; - // Create generic table request PolarisModels.CreateGenericTableRequest tableRequest = new PolarisModels.CreateGenericTableRequest( - tableName, - TABLE_FORMAT_LANCE, - request.getLocation(), // location from request - comment, // doc field from comment property - properties); + tableName, TABLE_FORMAT_LANCE, request.getLocation(), comment, properties); - // Create table using Generic Table API PolarisModels.LoadGenericTableResponse response = restClient.post( "/namespaces/" + namespacePath + "/generic-tables", @@ -323,22 +266,12 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request CreateEmptyTableResponse result = new CreateEmptyTableResponse(); result.setLocation(response.getTable().getBaseLocation()); - Map resultProps = new HashMap<>(response.getTable().getProperties()); - if (response.getTable().getDoc() != null) { - resultProps.put("comment", response.getTable().getDoc()); - } - result.setProperties(resultProps); return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("409")) { - throw LanceNamespaceException.conflict( - "Table already exists", - "TableAlreadyExists", - tableId.stringStyleId(), - "Table already exists: " + tableId.stringStyleId()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new TableAlreadyExistsException("Table already exists: " + tableId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to create table", "ServerError", tableId.stringStyleId(), e.getMessage()); + throw new InternalException("Failed to create table: " + e.getMessage()); } } @@ -349,13 +282,11 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { tableId.levels() >= 2, "Table identifier must have at least 2 levels"); try { - // Split into namespace and table name List parts = tableId.listStyleId(); String tableName = parts.get(parts.size() - 1); List namespaceParts = parts.subList(0, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); - // Get table using Generic Table API PolarisModels.LoadGenericTableResponse response = restClient.get( "/namespaces/" + namespacePath + "/generic-tables/" + tableName, @@ -363,12 +294,8 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { PolarisModels.GenericTable table = response.getTable(); - // Verify it's a Lance table if (!TABLE_FORMAT_LANCE.equals(table.getFormat())) { - throw LanceNamespaceException.badRequest( - "Invalid table format", - "InvalidTableFormat", - tableId.stringStyleId(), + throw new InvalidInputException( String.format( "Table %s is not a Lance table (format: %s)", tableId.stringStyleId(), table.getFormat())); @@ -376,25 +303,13 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { DescribeTableResponse result = new DescribeTableResponse(); result.setLocation(table.getBaseLocation()); - Map resultProps = new HashMap<>(); - if (table.getProperties() != null) { - resultProps.putAll(table.getProperties()); - } - if (table.getDoc() != null) { - resultProps.put("comment", table.getDoc()); - } - result.setProperties(resultProps); + result.setStorageOptions(table.getProperties()); return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Table not found", - "NoSuchTable", - tableId.stringStyleId(), - "Table not found: " + tableId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to describe table", "ServerError", tableId.stringStyleId(), e.getMessage()); + throw new InternalException("Failed to describe table: " + e.getMessage()); } } @@ -407,14 +322,12 @@ public ListTablesResponse listTables(ListTablesRequest request) { try { String namespacePath = namespaceId.stringStyleId(); - // List tables using Generic Table API PolarisModels.ListGenericTablesResponse response = restClient.get( "/namespaces/" + namespacePath + "/generic-tables", PolarisModels.ListGenericTablesResponse.class); ListTablesResponse result = new ListTablesResponse(); - // Convert table identifiers to table names only Set tableNames = new LinkedHashSet<>(); if (response.getIdentifiers() != null) { for (PolarisModels.TableIdentifier id : response.getIdentifiers()) { @@ -423,86 +336,49 @@ public ListTablesResponse listTables(ListTablesRequest request) { } result.setTables(tableNames); return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NoSuchNamespace", - namespaceId.stringStyleId(), - "Namespace not found: " + namespaceId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + namespaceId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to list tables", "ServerError", namespaceId.stringStyleId(), e.getMessage()); + throw new InternalException("Failed to list tables: " + e.getMessage()); } } @Override - public DropTableResponse dropTable(DropTableRequest request) { + public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() >= 2, "Table identifier must have at least 2 levels"); try { - // Split into namespace and table name List parts = tableId.listStyleId(); String tableName = parts.get(parts.size() - 1); List namespaceParts = parts.subList(0, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); - // Drop table using Generic Table API - restClient.delete("/namespaces/" + namespacePath + "/generic-tables/" + tableName); + PolarisModels.LoadGenericTableResponse getResponse = + restClient.get( + "/namespaces/" + namespacePath + "/generic-tables/" + tableName, + PolarisModels.LoadGenericTableResponse.class); - LOG.info("Dropped table: {}.{}", namespacePath, tableName); + String location = getResponse.getTable().getBaseLocation(); + restClient.delete("/namespaces/" + namespacePath + "/generic-tables/" + tableName); - DropTableResponse result = new DropTableResponse(); - // DropTableResponse has no fields to set based on the model + DeregisterTableResponse result = new DeregisterTableResponse(); + result.setLocation(location); return result; - } catch (IOException e) { - if (e.getMessage() != null && e.getMessage().contains("404")) { - throw LanceNamespaceException.notFound( - "Table not found", - "NoSuchTable", - tableId.stringStyleId(), - "Table not found: " + tableId.stringStyleId()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + tableId.stringStyleId()); } - throw LanceNamespaceException.serverError( - "Failed to drop table", "ServerError", tableId.stringStyleId(), e.getMessage()); - } - } - - // These methods are not part of the LanceNamespace interface - // They were removed as they don't exist in the interface - private Dataset openTableInternal(String location, Schema schema) { - try { - return Dataset.open(location, allocator); - } catch (Exception e) { - throw LanceNamespaceException.serverError( - "Failed to open Lance table", - "DatasetError", - location, - "Failed to open Lance table at: " + location + ": " + e.getMessage()); + throw new InternalException("Failed to deregister table: " + e.getMessage()); } } - private Dataset createTableInternal(String location, Schema schema, WriteParams params) { - try { - return Dataset.create(allocator, location, schema, params); - } catch (Exception e) { - throw LanceNamespaceException.serverError( - "Failed to create Lance table", - "DatasetError", - location, - "Failed to create Lance table at: " + location + ": " + e.getMessage()); - } - } - - public void close() { + @Override + public void close() throws IOException { if (restClient != null) { - try { - restClient.close(); - } catch (IOException e) { - LOG.warn("Failed to close REST client", e); - } + restClient.close(); } } } diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java index 8329b39..9fd8e05 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java @@ -13,7 +13,7 @@ */ package org.lance.namespace.polaris; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.InvalidInputException; import java.util.Map; @@ -55,10 +55,7 @@ public PolarisNamespaceConfig(Map properties) { private String getRequiredProperty(Map properties, String key) { String value = properties.get(key); if (value == null || value.trim().isEmpty()) { - throw LanceNamespaceException.badRequest( - "Missing required configuration", - "ConfigurationError", - key, + throw new InvalidInputException( String.format("Required configuration property '%s' is not set", key)); } return value.trim(); @@ -66,35 +63,20 @@ private String getRequiredProperty(Map properties, String key) { private void validateConfig() { if (!endpoint.startsWith("http://") && !endpoint.startsWith("https://")) { - throw LanceNamespaceException.badRequest( - "Invalid endpoint format", - "ConfigurationError", - POLARIS_ENDPOINT, + throw new InvalidInputException( "Polaris endpoint must start with http:// or https://: " + endpoint); } if (connectTimeout <= 0) { - throw LanceNamespaceException.badRequest( - "Invalid timeout value", - "ConfigurationError", - POLARIS_CONNECT_TIMEOUT, - "Connect timeout must be positive: " + connectTimeout); + throw new InvalidInputException("Connect timeout must be positive: " + connectTimeout); } if (readTimeout <= 0) { - throw LanceNamespaceException.badRequest( - "Invalid timeout value", - "ConfigurationError", - POLARIS_READ_TIMEOUT, - "Read timeout must be positive: " + readTimeout); + throw new InvalidInputException("Read timeout must be positive: " + readTimeout); } if (maxRetries < 0) { - throw LanceNamespaceException.badRequest( - "Invalid retry value", - "ConfigurationError", - POLARIS_MAX_RETRIES, - "Max retries cannot be negative: " + maxRetries); + throw new InvalidInputException("Max retries cannot be negative: " + maxRetries); } } diff --git a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java index d45dc78..a01a326 100644 --- a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java +++ b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java @@ -13,19 +13,19 @@ */ package org.lance.namespace.polaris; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -200,7 +200,7 @@ public void testNamespaceExists() throws IOException { public void testNamespaceNotExists() throws IOException { when(restClient.get( eq("/namespaces/test_catalog.schema1"), eq(PolarisModels.NamespaceResponse.class))) - .thenThrow(new IOException("404 Not Found")); + .thenThrow(new org.lance.namespace.rest.RestClientException(404, "Not Found")); NamespaceExistsRequest request = new NamespaceExistsRequest(); request.setId(Arrays.asList("test_catalog", "schema1")); @@ -234,13 +234,10 @@ public void testCreateEmptyTable() throws IOException { CreateEmptyTableRequest request = new CreateEmptyTableRequest(); request.setId(Arrays.asList("test_catalog", "schema1", "test_table")); request.setLocation("s3://bucket/path/to/table"); - request.setProperties(Collections.singletonMap("comment", "Test table")); CreateEmptyTableResponse response = namespace.createEmptyTable(request); assertThat(response.getLocation()).isEqualTo("s3://bucket/path/to/table"); - assertThat(response.getProperties()).containsEntry("managed_by", "storage"); - assertThat(response.getProperties()).containsEntry("comment", "Test table"); } @Test @@ -269,8 +266,6 @@ public void testDescribeTable() throws IOException { DescribeTableResponse response = namespace.describeTable(request); assertThat(response.getLocation()).isEqualTo("s3://bucket/path/to/table"); - assertThat(response.getProperties()).containsEntry("comment", "Test table"); - assertThat(response.getProperties()).containsEntry("managed_by", "storage"); } @Test @@ -326,13 +321,27 @@ public void testListTables() throws IOException { } @Test - public void testDropTable() throws IOException { - DropTableRequest request = new DropTableRequest(); + public void testDeregisterTable() throws IOException { + PolarisModels.GenericTable mockTable = new PolarisModels.GenericTable(); + mockTable.setName("test_table"); + mockTable.setFormat("lance"); + mockTable.setBaseLocation("s3://bucket/path/to/table"); + + PolarisModels.LoadGenericTableResponse mockResponse = + new PolarisModels.LoadGenericTableResponse(); + mockResponse.setTable(mockTable); + + when(restClient.get( + eq("/namespaces/test_catalog.schema1/generic-tables/test_table"), + eq(PolarisModels.LoadGenericTableResponse.class))) + .thenReturn(mockResponse); + + DeregisterTableRequest request = new DeregisterTableRequest(); request.setId(Arrays.asList("test_catalog", "schema1", "test_table")); - DropTableResponse response = namespace.dropTable(request); + DeregisterTableResponse response = namespace.deregisterTable(request); + assertThat(response.getLocation()).isEqualTo("s3://bucket/path/to/table"); verify(restClient).delete("/namespaces/test_catalog.schema1/generic-tables/test_table"); - // Response doesn't have getId() method, just verify the delete was called } } diff --git a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java index 06a3815..52f5641 100644 --- a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java +++ b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java @@ -13,17 +13,17 @@ */ package org.lance.namespace.polaris; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; +import org.lance.namespace.model.CreateEmptyTableRequest; +import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; +import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; -import org.lance.namespace.model.DropTableRequest; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -248,22 +248,20 @@ public void testTableOperations() { String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8); - // Create table - CreateTableRequest createRequest = new CreateTableRequest(); + // Create empty table + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); createRequest.setId(Arrays.asList(testCatalog, testNamespace, tableName)); - createRequest.setLocation("s3://test-bucket/lance/" + tableName); - createRequest.setProperties(Collections.singletonMap("comment", "Test table")); + createRequest.setLocation("/tmp/polaris-test/" + testNamespace + "/" + tableName); - CreateTableResponse createResponse = namespace.createTable(createRequest, new byte[0]); - assertThat(createResponse.getLocation()).isEqualTo("s3://test-bucket/lance/" + tableName); - assertThat(createResponse.getProperties()).containsEntry("comment", "Test table"); + CreateEmptyTableResponse createResponse = namespace.createEmptyTable(createRequest); + assertThat(createResponse.getLocation()).isNotNull(); // Describe table DescribeTableRequest describeRequest = new DescribeTableRequest(); describeRequest.setId(Arrays.asList(testCatalog, testNamespace, tableName)); DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); - assertThat(describeResponse.getLocation()).isEqualTo("s3://test-bucket/lance/" + tableName); + assertThat(describeResponse.getLocation()).isNotNull(); // Check table exists TableExistsRequest existsRequest = new TableExistsRequest(); @@ -277,10 +275,10 @@ public void testTableOperations() { ListTablesResponse listResponse = namespace.listTables(listRequest); assertThat(listResponse.getTables()).contains(tableName); - // Drop table - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(Arrays.asList(testCatalog, testNamespace, tableName)); - namespace.dropTable(dropRequest); + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(testCatalog, testNamespace, tableName)); + namespace.deregisterTable(deregisterRequest); // Verify table doesn't exist assertThatThrownBy(() -> namespace.tableExists(existsRequest)) @@ -289,22 +287,19 @@ public void testTableOperations() { } @Test - public void testCreateTableWithInvalidFormat() { + public void testCreateEmptyTableWithLocation() { // Create namespace first CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); nsRequest.setId(Arrays.asList(testCatalog, testNamespace)); namespace.createNamespace(nsRequest); - // Try to describe a non-Lance table (would need to be created through Polaris directly) - // This test demonstrates the format validation - - // For now, just verify Lance tables work correctly + // Create an empty Lance table with location String tableName = "lance_table"; - CreateTableRequest createRequest = new CreateTableRequest(); + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); createRequest.setId(Arrays.asList(testCatalog, testNamespace, tableName)); - createRequest.setLocation("s3://test-bucket/lance/" + tableName); + createRequest.setLocation("/tmp/polaris-test/" + testNamespace + "/" + tableName); - CreateTableResponse response = namespace.createTable(createRequest, new byte[0]); - assertThat(response.getProperties()).containsEntry("table_type", "lance"); + CreateEmptyTableResponse response = namespace.createEmptyTable(createRequest); + assertThat(response.getLocation()).isNotNull(); } } diff --git a/java/lance-namespace-unity/README.md b/java/lance-namespace-unity/README.md index c42e2c0..1b2a39c 100644 --- a/java/lance-namespace-unity/README.md +++ b/java/lance-namespace-unity/README.md @@ -70,11 +70,11 @@ CreateNamespaceRequest request = new CreateNamespaceRequest(); request.setId(Arrays.asList("unity", "my_schema")); namespace.createNamespace(request); -// Create a table -CreateTableRequest tableRequest = new CreateTableRequest(); +// Declare a table entry (use lance SDK to create the actual table) +DeclareTableRequest tableRequest = new DeclareTableRequest(); tableRequest.setId(Arrays.asList("unity", "my_schema", "my_table")); -tableRequest.setJsonArrowSchema(arrowSchema); -namespace.createTable(tableRequest); +tableRequest.setLocation("/path/to/storage/my_schema/my_table"); +namespace.declareTable(tableRequest); ``` ## Integration with Unity Catalog diff --git a/java/lance-namespace-unity/pom.xml b/java/lance-namespace-unity/pom.xml index 3ffe9d6..767707a 100644 --- a/java/lance-namespace-unity/pom.xml +++ b/java/lance-namespace-unity/pom.xml @@ -18,10 +18,18 @@ Unity Catalog namespace implementation for Lance + + org.lance + lance-namespace-impls-core + org.lance lance-core + + org.lance + lance-namespace-core + org.lance lance-namespace-apache-client @@ -54,6 +62,18 @@ test + + org.junit.jupiter + junit-jupiter + test + + + + org.assertj + assertj-core + test + + org.mockito mockito-core diff --git a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java index 0579ef3..4d6eee7 100644 --- a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java +++ b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java @@ -13,26 +13,25 @@ */ package org.lance.namespace.unity; -import com.lancedb.lance.Dataset; -import com.lancedb.lance.WriteParams; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; -import org.lance.namespace.ObjectIdentifier; +import org.lance.namespace.errors.InternalException; +import org.lance.namespace.errors.InvalidInputException; +import org.lance.namespace.errors.NamespaceAlreadyExistsException; +import org.lance.namespace.errors.NamespaceNotFoundException; +import org.lance.namespace.errors.TableAlreadyExistsException; +import org.lance.namespace.errors.TableNotFoundException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; -import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -40,8 +39,8 @@ import org.lance.namespace.model.NamespaceExistsRequest; import org.lance.namespace.model.TableExistsRequest; import org.lance.namespace.rest.RestClient; -import org.lance.namespace.util.ArrowIpcUtil; -import org.lance.namespace.util.JsonArrowSchemaConverter; +import org.lance.namespace.rest.RestClientException; +import org.lance.namespace.util.ObjectIdentifier; import org.lance.namespace.util.ValidationUtil; import org.apache.arrow.memory.BufferAllocator; @@ -52,6 +51,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -60,10 +60,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** Unity Catalog namespace implementation for Lance. */ -public class UnityNamespace implements LanceNamespace { +public class UnityNamespace implements LanceNamespace, Closeable { private static final Logger LOG = LoggerFactory.getLogger(UnityNamespace.class); private static final String TABLE_TYPE_LANCE = "lance"; private static final String TABLE_TYPE_EXTERNAL = "EXTERNAL"; @@ -80,19 +81,15 @@ public void initialize(Map configProperties, BufferAllocator all this.allocator = allocator; this.config = new UnityNamespaceConfig(configProperties); - // Build REST client with authentication if provided RestClient.Builder clientBuilder = RestClient.builder() .baseUrl(config.getFullApiUrl()) - .connectTimeout(config.getConnectTimeout()) - .readTimeout(config.getReadTimeout()) + .connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS) + .readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS) .maxRetries(config.getMaxRetries()); - // Add auth token if provided if (config.getAuthToken() != null) { - Map headers = new HashMap<>(); - headers.put("Authorization", "Bearer " + config.getAuthToken()); - clientBuilder.defaultHeaders(headers); + clientBuilder.authToken(config.getAuthToken()); } this.restClient = clientBuilder.build(); @@ -110,7 +107,6 @@ public String namespaceId() { public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); - // Unity supports 3-level namespace: catalog.schema.table ValidationUtil.checkArgument( nsId.levels() <= 2, "Expect at most 2-level namespace but get %s", nsId); @@ -118,30 +114,24 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { List namespaces; if (nsId.levels() == 0) { - // Return the configured catalog as the only top-level namespace namespaces = Collections.singletonList(config.getCatalog()); } else if (nsId.levels() == 1) { - // List schemas in the catalog String catalog = nsId.levelAtListPos(0); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.notFound( - "Catalog not found", - "CATALOG_NOT_FOUND", - catalog, - "Expected: " + config.getCatalog()); + throw new NamespaceNotFoundException( + "Catalog not found. Expected: " + config.getCatalog()); } - Map params = new HashMap<>(); - params.put("catalog_name", catalog); + String path = "/schemas?catalog_name=" + catalog; if (request.getLimit() != null) { - params.put("max_results", request.getLimit().toString()); + path += "&max_results=" + request.getLimit(); } if (request.getPageToken() != null) { - params.put("page_token", request.getPageToken()); + path += "&page_token=" + request.getPageToken(); } UnityModels.ListSchemasResponse response = - restClient.get("/schemas", params, UnityModels.ListSchemasResponse.class); + restClient.get(path, UnityModels.ListSchemasResponse.class); if (response != null && response.getSchemas() != null) { namespaces = @@ -162,8 +152,8 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { response.setNamespaces(resultNamespaces); return response; - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to list namespaces: " + e.getMessage()); + } catch (RestClientException e) { + throw new InternalException("Failed to list namespaces: " + e.getMessage()); } } @@ -176,11 +166,8 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { String schema = nsId.levelAtListPos(1); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.badRequest( - "Cannot create namespace in catalog", - "INVALID_CATALOG", - catalog, - "Expected: " + config.getCatalog()); + throw new InvalidInputException( + "Cannot create namespace in catalog. Expected: " + config.getCatalog()); } try { @@ -196,17 +183,12 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { response.setProperties(schemaInfo.getProperties()); return response; - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Namespace already exists", - "NAMESPACE_EXISTS", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new NamespaceAlreadyExistsException( + "Namespace already exists: " + request.getId().toString()); } - throw new LanceNamespaceException(500, "Failed to create namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to create namespace: " + e.getMessage()); + throw new InternalException("Failed to create namespace: " + e.getMessage()); } } @@ -219,8 +201,8 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ String schema = nsId.levelAtListPos(1); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.notFound( - "Catalog not found", "CATALOG_NOT_FOUND", catalog, "Expected: " + config.getCatalog()); + throw new NamespaceNotFoundException( + "Catalog not found: " + catalog + ". Expected: " + config.getCatalog()); } try { @@ -232,17 +214,11 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ response.setProperties(schemaInfo.getProperties()); return response; - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - throw LanceNamespaceException.notFound( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new NamespaceNotFoundException("Namespace not found: " + request.getId().toString()); } - throw new LanceNamespaceException(500, "Failed to describe namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to describe namespace: " + e.getMessage()); + throw new InternalException("Failed to describe namespace: " + e.getMessage()); } } @@ -260,34 +236,22 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { String schema = nsId.levelAtListPos(1); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.badRequest( - "Cannot drop namespace in catalog", - "INVALID_CATALOG", - catalog, - "Expected: " + config.getCatalog()); + throw new InvalidInputException( + "Cannot drop namespace in catalog. Expected: " + config.getCatalog()); } try { String fullName = catalog + "." + schema; - Map params = new HashMap<>(); - if (request.getBehavior() != null - && request.getBehavior() == DropNamespaceRequest.BehaviorEnum.CASCADE) { - params.put("force", "true"); - } - - restClient.delete("/schemas/" + fullName, params); + String path = "/schemas/" + fullName; - DropNamespaceResponse response = new DropNamespaceResponse(); - return response; + restClient.delete(path); + return new DropNamespaceResponse(); - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - DropNamespaceResponse response = new DropNamespaceResponse(); - return response; + } catch (RestClientException e) { + if (e.isNotFound()) { + return new DropNamespaceResponse(); } - throw new LanceNamespaceException(500, "Failed to drop namespace: " + e.getMessage()); - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to drop namespace: " + e.getMessage()); + throw new InternalException("Failed to drop namespace: " + e.getMessage()); } } @@ -300,27 +264,24 @@ public ListTablesResponse listTables(ListTablesRequest request) { String schema = nsId.levelAtListPos(1); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.notFound( - "Catalog not found", "CATALOG_NOT_FOUND", catalog, "Expected: " + config.getCatalog()); + throw new NamespaceNotFoundException( + "Catalog not found: " + catalog + ". Expected: " + config.getCatalog()); } try { - Map params = new HashMap<>(); - params.put("catalog_name", catalog); - params.put("schema_name", schema); + String path = "/tables?catalog_name=" + catalog + "&schema_name=" + schema; if (request.getLimit() != null) { - params.put("max_results", request.getLimit().toString()); + path += "&max_results=" + request.getLimit(); } if (request.getPageToken() != null) { - params.put("page_token", request.getPageToken()); + path += "&page_token=" + request.getPageToken(); } UnityModels.ListTablesResponse unityResponse = - restClient.get("/tables", params, UnityModels.ListTablesResponse.class); + restClient.get(path, UnityModels.ListTablesResponse.class); List tables = Collections.emptyList(); if (unityResponse != null && unityResponse.getTables() != null) { - // Filter only Lance tables tables = unityResponse.getTables().stream() .filter(this::isLanceTable) @@ -335,96 +296,8 @@ public ListTablesResponse listTables(ListTablesRequest request) { response.setTables(resultTables); return response; - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to list tables: " + e.getMessage()); - } - } - - @Override - public CreateTableResponse createTable(CreateTableRequest request, byte[] requestData) { - // Validate that requestData is a valid Arrow IPC stream - ValidationUtil.checkNotNull( - requestData, "Request data (Arrow IPC stream) is required for createTable"); - ValidationUtil.checkArgument( - requestData.length > 0, "Request data (Arrow IPC stream) cannot be empty"); - - ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); - ValidationUtil.checkArgument( - tableId.levels() == 3, "Expect a 3-level table identifier but get %s", tableId); - - String catalog = tableId.levelAtListPos(0); - String schema = tableId.levelAtListPos(1); - String table = tableId.levelAtListPos(2); - - if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.badRequest( - "Cannot create table in catalog", - "INVALID_CATALOG", - catalog, - "Expected: " + config.getCatalog()); - } - - try { - // First create an empty Lance table dataset - String tablePath = config.getRoot() + "/" + catalog + "/" + schema + "/" + table; - // Extract schema from Arrow IPC stream - JsonArrowSchema jsonSchema; - try { - jsonSchema = ArrowIpcUtil.extractSchemaFromIpc(requestData); - } catch (IOException e) { - throw LanceNamespaceException.badRequest( - "Invalid Arrow IPC stream: " + e.getMessage(), - "INVALID_ARROW_IPC", - catalog + "." + schema + "." + table, - "Failed to extract schema from Arrow IPC stream"); - } - Schema arrowSchema = JsonArrowSchemaConverter.convertToArrowSchema(jsonSchema); - - WriteParams writeParams = - new WriteParams.Builder().withMode(WriteParams.WriteMode.CREATE).build(); - - Dataset dataset = Dataset.create(allocator, tablePath, arrowSchema, writeParams); - dataset.close(); - - // Create Unity table metadata - UnityModels.CreateTable createTable = new UnityModels.CreateTable(); - createTable.setName(table); - createTable.setCatalogName(catalog); - createTable.setSchemaName(schema); - createTable.setTableType(TABLE_TYPE_EXTERNAL); - // Unity doesn't recognize LANCE format, use TEXT as a generic format for external tables - // The actual format is determined by the table_type=lance property - createTable.setDataSourceFormat("TEXT"); - createTable.setColumns(convertArrowSchemaToUnityColumns(arrowSchema)); - createTable.setStorageLocation(tablePath); - - Map properties = new HashMap<>(); - properties.put(TABLE_TYPE_KEY, TABLE_TYPE_LANCE); - if (request.getProperties() != null) { - properties.putAll(request.getProperties()); - } - createTable.setProperties(properties); - - UnityModels.TableInfo tableInfo = - restClient.post("/tables", createTable, UnityModels.TableInfo.class); - - CreateTableResponse response = new CreateTableResponse(); - response.setLocation(tablePath); - response.setVersion(1L); - response.setProperties(tableInfo.getProperties()); - return response; - - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - request.getId().toString(), - e.getResponseBody()); - } - throw new LanceNamespaceException(500, "Failed to create table: " + e.getMessage()); - } catch (Exception e) { - throw new LanceNamespaceException(500, "Failed to create table: " + e.getMessage()); + } catch (RestClientException e) { + throw new InternalException("Failed to list tables: " + e.getMessage()); } } @@ -439,29 +312,23 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request String table = tableId.levelAtListPos(2); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.badRequest( - "Cannot create empty table in catalog", - "INVALID_CATALOG", - catalog, - "Expected: " + config.getCatalog()); + throw new InvalidInputException( + "Cannot create empty table in catalog. Expected: " + config.getCatalog()); } try { - // Determine table location String tablePath = request.getLocation(); if (tablePath == null || tablePath.isEmpty()) { tablePath = config.getRoot() + "/" + catalog + "/" + schema + "/" + table; } - // Create Unity table metadata without creating Lance dataset UnityModels.CreateTable createTable = new UnityModels.CreateTable(); createTable.setName(table); createTable.setCatalogName(catalog); createTable.setSchemaName(schema); createTable.setTableType(TABLE_TYPE_EXTERNAL); - // Unity doesn't recognize LANCE format, use TEXT as a generic format for external tables createTable.setDataSourceFormat("TEXT"); - // For empty table, create minimal schema with just an ID column + List columns = new ArrayList<>(); UnityModels.ColumnInfo idColumn = new UnityModels.ColumnInfo(); idColumn.setName("__placeholder_id"); @@ -476,9 +343,6 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request Map properties = new HashMap<>(); properties.put(TABLE_TYPE_KEY, TABLE_TYPE_LANCE); - if (request.getProperties() != null) { - properties.putAll(request.getProperties()); - } createTable.setProperties(properties); UnityModels.TableInfo tableInfo = @@ -486,20 +350,14 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request CreateEmptyTableResponse response = new CreateEmptyTableResponse(); response.setLocation(tablePath); - response.setProperties(tableInfo.getProperties()); return response; - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 409) { - throw LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - request.getId().toString(), - e.getResponseBody()); + } catch (RestClientException e) { + if (e.isConflict()) { + throw new TableAlreadyExistsException( + "Table already exists: " + request.getId().toString()); } - throw new LanceNamespaceException(500, "Failed to create empty table: " + e.getMessage()); - } catch (Exception e) { - throw new LanceNamespaceException(500, "Failed to create empty table: " + e.getMessage()); + throw new InternalException("Failed to create empty table: " + e.getMessage()); } } @@ -514,8 +372,8 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { String table = tableId.levelAtListPos(2); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.notFound( - "Catalog not found", "CATALOG_NOT_FOUND", catalog, "Expected: " + config.getCatalog()); + throw new NamespaceNotFoundException( + "Catalog not found: " + catalog + ". Expected: " + config.getCatalog()); } try { @@ -524,27 +382,19 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { restClient.get("/tables/" + fullName, UnityModels.TableInfo.class); if (!isLanceTable(tableInfo)) { - throw LanceNamespaceException.badRequest( - "Not a Lance table", - "INVALID_TABLE", - request.getId().toString(), - "Table is not managed by Lance"); + throw new InvalidInputException("Not a Lance table: " + request.getId().toString()); } DescribeTableResponse response = new DescribeTableResponse(); response.setLocation(tableInfo.getStorageLocation()); - response.setProperties(tableInfo.getProperties()); - + response.setStorageOptions(tableInfo.getProperties()); return response; - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - throw LanceNamespaceException.notFound( - "Table not found", "TABLE_NOT_FOUND", request.getId().toString(), e.getResponseBody()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + request.getId().toString()); } - throw new LanceNamespaceException(500, "Failed to describe table: " + e.getMessage()); - } catch (Exception e) { - throw new LanceNamespaceException(500, "Failed to describe table: " + e.getMessage()); + throw new InternalException("Failed to describe table: " + e.getMessage()); } } @@ -554,7 +404,7 @@ public void tableExists(TableExistsRequest request) { } @Override - public DropTableResponse dropTable(DropTableRequest request) { + public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() == 3, "Expect a 3-level table identifier but get %s", tableId); @@ -564,61 +414,35 @@ public DropTableResponse dropTable(DropTableRequest request) { String table = tableId.levelAtListPos(2); if (!catalog.equals(config.getCatalog())) { - throw LanceNamespaceException.badRequest( - "Cannot drop table in catalog", - "INVALID_CATALOG", - catalog, - "Expected: " + config.getCatalog()); + throw new NamespaceNotFoundException( + "Catalog not found: " + catalog + ". Expected: " + config.getCatalog()); } try { String fullName = catalog + "." + schema + "." + table; - - // First get the table info to check if it's a Lance table - UnityModels.TableInfo tableInfo = null; - try { - tableInfo = restClient.get("/tables/" + fullName, UnityModels.TableInfo.class); - } catch (RestClient.RestClientException e) { - if (e.getStatusCode() == 404) { - DropTableResponse response = new DropTableResponse(); - response.setId(request.getId()); - return response; - } - throw e; - } + UnityModels.TableInfo tableInfo = + restClient.get("/tables/" + fullName, UnityModels.TableInfo.class); if (!isLanceTable(tableInfo)) { - throw LanceNamespaceException.badRequest( - "Not a Lance table", - "INVALID_TABLE", - request.getId().toString(), - "Table is not managed by Lance"); + throw new InvalidInputException("Not a Lance table: " + request.getId().toString()); } - // Delete from Unity + String location = tableInfo.getStorageLocation(); restClient.delete("/tables/" + fullName); - // Delete Lance dataset data - try { - Dataset.drop(tableInfo.getStorageLocation(), Collections.emptyMap()); - } catch (Exception e) { - // Log warning but continue - Unity metadata already deleted - LOG.warn( - "Failed to delete Lance dataset at {}: {}", - tableInfo.getStorageLocation(), - e.getMessage()); - } - - DropTableResponse response = new DropTableResponse(); - response.setId(request.getId()); - response.setLocation(tableInfo.getStorageLocation()); + DeregisterTableResponse response = new DeregisterTableResponse(); + response.setLocation(location); return response; - } catch (IOException e) { - throw new LanceNamespaceException(500, "Failed to drop table: " + e.getMessage()); + } catch (RestClientException e) { + if (e.isNotFound()) { + throw new TableNotFoundException("Table not found: " + request.getId().toString()); + } + throw new InternalException("Failed to deregister table: " + e.getMessage()); } } + @Override public void close() throws IOException { if (restClient != null) { restClient.close(); @@ -642,13 +466,8 @@ private List convertArrowSchemaToUnityColumns(Schema arr columnInfo.setTypeText(unityType); columnInfo.setTypeJson(convertArrowTypeToUnityTypeJson(field.getType())); columnInfo.setTypeName(unityType); - columnInfo.setTypeScale(null); - columnInfo.setTypePrecision(null); - columnInfo.setTypeIntervalType(null); columnInfo.setPosition(columns.size()); - columnInfo.setComment(null); columnInfo.setNullable(field.isNullable()); - columnInfo.setPartitionIndex(null); columns.add(columnInfo); } return columns; @@ -678,7 +497,6 @@ private String convertArrowTypeToUnityType(ArrowType arrowType) { } else if (arrowType instanceof ArrowType.Timestamp) { return "TIMESTAMP"; } - // Default fallback return "STRING"; } @@ -706,7 +524,6 @@ private String convertArrowTypeToUnityTypeJson(ArrowType arrowType) { } else if (arrowType instanceof ArrowType.Timestamp) { return "{\"type\":\"timestamp\"}"; } - // Default fallback return "{\"type\":\"string\"}"; } } diff --git a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespaceConfig.java b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespaceConfig.java index 5d1c2a4..76343b8 100644 --- a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespaceConfig.java +++ b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespaceConfig.java @@ -13,8 +13,7 @@ */ package org.lance.namespace.unity; -import org.lance.namespace.util.PropertyUtil; - +import java.util.HashMap; import java.util.Map; /** Configuration for Unity Catalog namespace. */ @@ -46,22 +45,40 @@ public class UnityNamespaceConfig { public UnityNamespaceConfig(Map properties) { this.properties = properties; - this.endpoint = PropertyUtil.propertyAsString(properties, ENDPOINT, null); + this.endpoint = properties.get(ENDPOINT); if (endpoint == null) { throw new IllegalArgumentException("Unity endpoint is required"); } - this.apiPath = PropertyUtil.propertyAsString(properties, API_PATH, DEFAULT_API_PATH); - this.authToken = PropertyUtil.propertyAsString(properties, AUTH_TOKEN, null); - this.catalog = PropertyUtil.propertyAsString(properties, CATALOG, null); + this.apiPath = properties.getOrDefault(API_PATH, DEFAULT_API_PATH); + this.authToken = properties.get(AUTH_TOKEN); + this.catalog = properties.get(CATALOG); if (catalog == null) { throw new IllegalArgumentException("Unity catalog is required"); } + + // Inline PropertyUtil.propertyAsInt + String connectTimeoutStr = properties.get(CONNECT_TIMEOUT); this.connectTimeout = - PropertyUtil.propertyAsInt(properties, CONNECT_TIMEOUT, DEFAULT_CONNECT_TIMEOUT); - this.readTimeout = PropertyUtil.propertyAsInt(properties, READ_TIMEOUT, DEFAULT_READ_TIMEOUT); - this.maxRetries = PropertyUtil.propertyAsInt(properties, MAX_RETRIES, DEFAULT_MAX_RETRIES); - this.root = PropertyUtil.propertyAsString(properties, ROOT, System.getProperty("user.dir")); - this.storageProperties = PropertyUtil.propertiesWithPrefix(properties, "storage."); + connectTimeoutStr != null ? Integer.parseInt(connectTimeoutStr) : DEFAULT_CONNECT_TIMEOUT; + + String readTimeoutStr = properties.get(READ_TIMEOUT); + this.readTimeout = + readTimeoutStr != null ? Integer.parseInt(readTimeoutStr) : DEFAULT_READ_TIMEOUT; + + String maxRetriesStr = properties.get(MAX_RETRIES); + this.maxRetries = maxRetriesStr != null ? Integer.parseInt(maxRetriesStr) : DEFAULT_MAX_RETRIES; + + this.root = properties.getOrDefault(ROOT, System.getProperty("user.dir")); + + // Inline PropertyUtil.propertiesWithPrefix + Map filteredStorageProperties = new HashMap<>(); + for (Map.Entry entry : properties.entrySet()) { + if (entry.getKey().startsWith("storage.")) { + filteredStorageProperties.put( + entry.getKey().substring("storage.".length()), entry.getValue()); + } + } + this.storageProperties = filteredStorageProperties; } public String getEndpoint() { diff --git a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java index efee14f..96f6a4c 100644 --- a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java +++ b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java @@ -14,28 +14,16 @@ package org.lance.namespace.unity; import org.lance.namespace.LanceNamespace; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; -import org.lance.namespace.model.CreateTableRequest; -import org.lance.namespace.model.CreateTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; -import org.lance.namespace.model.DescribeTableRequest; -import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; import org.lance.namespace.model.DropNamespaceResponse; -import org.lance.namespace.model.DropTableRequest; -import org.lance.namespace.model.DropTableResponse; -import org.lance.namespace.model.JsonArrowDataType; -import org.lance.namespace.model.JsonArrowField; -import org.lance.namespace.model.JsonArrowSchema; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; -import org.lance.namespace.model.ListTablesRequest; -import org.lance.namespace.model.ListTablesResponse; import org.lance.namespace.model.NamespaceExistsRequest; -import org.lance.namespace.model.TableExistsRequest; import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; @@ -50,11 +38,9 @@ import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.UUID; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -153,7 +139,7 @@ public void tearDown() throws IOException { try { DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(UNITY_CATALOG, TEST_SCHEMA)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors @@ -243,90 +229,6 @@ public void testCreateDuplicateSchema() { } } - @Test - public void testTableLifecycle() throws IOException { - // Create schema first - CreateNamespaceRequest createNsRequest = new CreateNamespaceRequest(); - createNsRequest.setId(Arrays.asList(UNITY_CATALOG, TEST_SCHEMA)); - namespace.createNamespace(createNsRequest); - - String tableName = "test_table_" + UUID.randomUUID().toString().replace("-", ""); - List tableId = Arrays.asList(UNITY_CATALOG, TEST_SCHEMA, tableName); - - // Create table - CreateTableRequest createTableRequest = new CreateTableRequest(); - createTableRequest.setId(tableId); - - // Create a simple Arrow schema - JsonArrowSchema arrowSchema = new JsonArrowSchema(); - JsonArrowField field1 = new JsonArrowField(); - field1.setName("id"); - - JsonArrowDataType intType = new JsonArrowDataType(); - intType.setType("int32"); - field1.setType(intType); - field1.setNullable(false); - - JsonArrowField field2 = new JsonArrowField(); - field2.setName("name"); - - JsonArrowDataType stringType = new JsonArrowDataType(); - stringType.setType("utf8"); - field2.setType(stringType); - field2.setNullable(true); - - arrowSchema.setFields(Arrays.asList(field1, field2)); - - Map tableProps = new HashMap<>(); - tableProps.put("custom_prop", "custom_value"); - createTableRequest.setProperties(tableProps); - // Unity tables are always managed by storage - - // Create proper Arrow IPC stream from the schema - byte[] arrowData = - org.lance.namespace.util.ArrowIpcUtil.createEmptyArrowIpcStream(arrowSchema); - CreateTableResponse createTableResponse = namespace.createTable(createTableRequest, arrowData); - assertNotNull(createTableResponse); - // Table created successfully - just verify non-null response - assertNotNull(createTableResponse.getLocation()); - - // Check table exists - TableExistsRequest existsRequest = new TableExistsRequest(); - existsRequest.setId(tableId); - namespace.tableExists(existsRequest); - - // List tables - ListTablesRequest listRequest = new ListTablesRequest(); - listRequest.setId(Arrays.asList(UNITY_CATALOG, TEST_SCHEMA)); - ListTablesResponse listResponse = namespace.listTables(listRequest); - assertNotNull(listResponse); - assertTrue(listResponse.getTables().contains(tableName)); - - // Describe table - DescribeTableRequest describeRequest = new DescribeTableRequest(); - describeRequest.setId(tableId); - DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); - assertNotNull(describeResponse); - assertNotNull(describeResponse.getLocation()); - assertNotNull(describeResponse.getProperties()); - assertEquals("storage", describeResponse.getProperties().get("managed_by")); - - // Drop table - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(tableId); - DropTableResponse dropResponse = namespace.dropTable(dropRequest); - assertNotNull(dropResponse); - assertEquals(tableId, dropResponse.getId()); - - // Check table no longer exists - should throw exception - try { - namespace.tableExists(existsRequest); - fail("Expected table not found exception"); - } catch (LanceNamespaceException e) { - assertTrue(e.getMessage().contains("not found")); - } - } - @Test public void testInvalidCatalog() { CreateNamespaceRequest request = new CreateNamespaceRequest(); diff --git a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java index e4442b1..f470e0d 100644 --- a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java +++ b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java @@ -13,17 +13,17 @@ */ package org.lance.namespace.unity; -import org.lance.namespace.LanceNamespaceException; +import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; -import org.lance.namespace.model.DropTableRequest; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -119,7 +119,8 @@ private static void ensureTestCatalogExists() { createConn.setRequestProperty("Content-Type", "application/json"); createConn.setDoOutput(true); - String body = String.format("{\"name\": \"%s\", \"comment\": \"Test catalog\"}", TEST_CATALOG); + String body = + String.format("{\"name\": \"%s\", \"comment\": \"Test catalog\"}", TEST_CATALOG); createConn.getOutputStream().write(body.getBytes()); int createResponse = createConn.getResponseCode(); @@ -160,7 +161,7 @@ public void tearDown() { // Clean up test schema DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors @@ -231,7 +232,8 @@ public void testTableOperations() { nsRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); namespace.createNamespace(nsRequest); - String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); + String tableName = + "test_table_" + UUID.randomUUID().toString().substring(0, 8).replace("-", ""); // Create empty table CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); @@ -247,7 +249,6 @@ public void testTableOperations() { DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); assertThat(describeResponse.getLocation()).contains(tableName); - assertThat(describeResponse.getProperties()).containsEntry("table_type", "lance"); // List tables ListTablesRequest listRequest = new ListTablesRequest(); @@ -256,10 +257,10 @@ public void testTableOperations() { ListTablesResponse listResponse = namespace.listTables(listRequest); assertThat(listResponse.getTables()).contains(tableName); - // Drop table - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(Arrays.asList(TEST_CATALOG, testSchema, tableName)); - namespace.dropTable(dropRequest); + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(TEST_CATALOG, testSchema, tableName)); + namespace.deregisterTable(deregisterRequest); // Verify table doesn't exist assertThatThrownBy(() -> namespace.describeTable(describeRequest)) @@ -283,7 +284,7 @@ public void testCascadeDropSchema() { // Drop schema with cascade DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); - dropRequest.setBehavior(DropNamespaceRequest.BehaviorEnum.CASCADE); + dropRequest.setBehavior("Cascade"); namespace.dropNamespace(dropRequest); // Verify schema doesn't exist diff --git a/java/pom.xml b/java/pom.xml index f0e3baf..b8f603e 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -57,8 +57,8 @@ UTF-8 - 1.0.0-beta.10 - 0.0.21 + 2.0.0-beta.4 + 0.4.0 15.0.0 5.8.2 @@ -86,6 +86,7 @@ + lance-namespace-impls-core lance-namespace-glue lance-namespace-hive2 lance-namespace-hive3 @@ -96,15 +97,25 @@ + + org.lance + lance-namespace-impls-core + ${project.version} + org.lance lance-core ${lance-core.version} + + org.lance + lance-namespace-core + ${lance-namespace.version} + org.lance lance-namespace-apache-client - ${lance-namespace-client.version} + ${lance-namespace.version} org.apache.arrow diff --git a/python/Makefile b/python/Makefile index 2abf855..7d25808 100644 --- a/python/Makefile +++ b/python/Makefile @@ -78,6 +78,23 @@ install-iceberg: test-iceberg: uv run pytest tests/test_iceberg.py +# ============================================================================ +# Polaris +# ============================================================================ + +.PHONY: lint-polaris +lint-polaris: + uv run ruff check src/lance_namespace_impls/polaris.py tests/test_polaris.py + uv run ruff format --check src/lance_namespace_impls/polaris.py tests/test_polaris.py + +.PHONY: install-polaris +install-polaris: + uv sync --extra polaris --extra dev + +.PHONY: test-polaris +test-polaris: + uv run pytest tests/test_polaris.py + # ============================================================================ # All # ============================================================================ diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..7ff4607 --- /dev/null +++ b/python/README.md @@ -0,0 +1,3 @@ +# Lance Namespace Implementations (Python) + +Third-party catalog implementations for Lance Namespace. diff --git a/python/pyproject.toml b/python/pyproject.toml index a93ef8d..2bbe336 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -26,7 +26,12 @@ hive2 = [ "thrift>=0.13.0", "hive-metastore-client>=1.0.0", ] +hive3 = [ + "thrift>=0.13.0", + "hive-metastore-client>=1.0.0", +] unity = [] +polaris = [] all = [ "boto3>=1.35.0", "botocore>=1.35.0", diff --git a/python/src/lance_namespace_impls/__init__.py b/python/src/lance_namespace_impls/__init__.py index 6d65254..ceacc6f 100644 --- a/python/src/lance_namespace_impls/__init__.py +++ b/python/src/lance_namespace_impls/__init__.py @@ -7,13 +7,49 @@ This package provides third-party catalog implementations for Lance Namespace: - GlueNamespace: AWS Glue Data Catalog - Hive2Namespace: Apache Hive 2.x Metastore +- Hive3Namespace: Apache Hive 3.x Metastore (with catalog support) - IcebergNamespace: Apache Iceberg REST Catalog +- PolarisNamespace: Apache Polaris Catalog - UnityNamespace: Unity Catalog + +Shared infrastructure: +- RestClient: Reusable HTTP client for REST API implementations +- RestClientException: Exception raised by RestClient +- NamespaceException: Base exception for namespace operations """ from lance_namespace_impls.glue import GlueNamespace -from lance_namespace_impls.hive import Hive2Namespace +from lance_namespace_impls.hive2 import Hive2Namespace +from lance_namespace_impls.hive3 import Hive3Namespace from lance_namespace_impls.iceberg import IcebergNamespace +from lance_namespace_impls.polaris import PolarisNamespace from lance_namespace_impls.unity import UnityNamespace +from lance_namespace_impls.rest_client import ( + RestClient, + RestClientException, + NamespaceException, + NamespaceNotFoundException, + NamespaceAlreadyExistsException, + TableNotFoundException, + TableAlreadyExistsException, + InvalidInputException, + InternalException, +) -__all__ = ["GlueNamespace", "Hive2Namespace", "IcebergNamespace", "UnityNamespace"] +__all__ = [ + "GlueNamespace", + "Hive2Namespace", + "Hive3Namespace", + "IcebergNamespace", + "PolarisNamespace", + "UnityNamespace", + "RestClient", + "RestClientException", + "NamespaceException", + "NamespaceNotFoundException", + "NamespaceAlreadyExistsException", + "TableNotFoundException", + "TableAlreadyExistsException", + "InvalidInputException", + "InternalException", +] diff --git a/python/src/lance_namespace_impls/glue.py b/python/src/lance_namespace_impls/glue.py index 3401b43..e12e70f 100644 --- a/python/src/lance_namespace_impls/glue.py +++ b/python/src/lance_namespace_impls/glue.py @@ -386,8 +386,11 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse location = table.get('StorageDescriptor', {}).get('Location') if not location: raise RuntimeError(f"Table has no location: {database_name}.{table_name}") - - return DescribeTableResponse(location=location) + + return DescribeTableResponse( + location=location, + storage_options=self.config.storage_options + ) except Exception as e: error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' if error_name == 'EntityNotFoundException': @@ -397,69 +400,23 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse raise RuntimeError(f"Failed to describe table: {e}") def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: - """Create a table with data from Arrow IPC stream.""" - database_name, table_name = self._parse_table_identifier(request.id) - - if not request_data: - raise ValueError("Request data (Arrow IPC stream) is required for create_table") - - # Determine table location - if request.location: - table_location = request.location - else: - # Use default location pattern - db_response = self.glue.get_database(Name=database_name) - db_location = db_response['Database'].get('LocationUri', '') - if db_location: - table_location = f"{db_location}/{table_name}.lance" - else: - # Use S3 default location - table_location = f"s3://lance-namespace/{database_name}/{table_name}.lance" - - # Extract table from Arrow IPC stream - try: - reader = pa.ipc.open_stream(pa.py_buffer(request_data)) - table = reader.read_all() - schema = table.schema - except Exception as e: - raise ValueError(f"Invalid Arrow IPC stream: {e}") - - # Write Lance dataset - lance.write_dataset(table, table_location, storage_options=self.config.storage_options) - - # Create Glue table entry - table_input = { - 'Name': table_name, - 'TableType': EXTERNAL_TABLE, - 'Parameters': { - TABLE_TYPE: LANCE_TABLE_TYPE, - }, - 'StorageDescriptor': { - 'Location': table_location, - 'Columns': self._convert_pyarrow_schema_to_glue_columns(schema) - } - } - - try: - self.glue.create_table( - DatabaseName=database_name, - TableInput=table_input - ) - return CreateTableResponse(location=table_location, version=1) - except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'AlreadyExistsException': - raise RuntimeError(f"Table already exists: {database_name}.{table_name}") - raise RuntimeError(f"Failed to create table: {e}") + """Create a table with data from Arrow IPC stream. + + This operation is not supported. Use create_empty_table to declare table metadata, + then use Lance SDK to create the actual table data. + """ + raise NotImplementedError( + "create_table is not supported. Use create_empty_table to declare table metadata, " + "then use Lance SDK to create the actual table data." + ) def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: """Create an empty table (metadata only) in Glue catalog.""" database_name, table_name = self._parse_table_identifier(request.id) # Determine table location - if request.location: - table_location = request.location - else: + table_location = getattr(request, 'location', None) + if not table_location: # Use default location pattern db_response = self.glue.get_database(Name=database_name) db_location = db_response['Database'].get('LocationUri', '') @@ -514,43 +471,15 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab return CreateEmptyTableResponse(location=table_location) def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table - deletes both the Lance dataset and Glue catalog entry.""" - database_name, table_name = self._parse_table_identifier(request.id) - - try: - # First get the table to find its location - response = self.glue.get_table( - DatabaseName=database_name, - Name=table_name - ) - table = response['Table'] - - # Verify it's a Lance table - if not self._is_lance_table(table): - raise RuntimeError(f"Table is not a Lance table: {database_name}.{table_name}") - - # Get the table location - location = table.get('StorageDescriptor', {}).get('Location') - if not location: - raise RuntimeError(f"Table has no location: {database_name}.{table_name}") - - # Drop the Lance dataset first - lance_dataset = lance.dataset(location, storage_options=self.config.storage_options) - lance_dataset.delete() - - # Then remove from Glue catalog - self.glue.delete_table( - DatabaseName=database_name, - Name=table_name - ) - return DropTableResponse() - except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': - raise RuntimeError(f"Table does not exist: {database_name}.{table_name}") - if isinstance(e, RuntimeError): - raise - raise RuntimeError(f"Failed to drop table: {e}") + """Drop a table - deletes both the Lance dataset and Glue catalog entry. + + This operation is not supported. Use deregister_table to remove table metadata, + then use Lance SDK to delete the actual table data if needed. + """ + raise NotImplementedError( + "drop_table is not supported. Use deregister_table to remove table metadata, " + "then use Lance SDK to delete the actual table data if needed." + ) def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: """Register an existing Lance table in Glue.""" diff --git a/python/src/lance_namespace_impls/hive.py b/python/src/lance_namespace_impls/hive2.py similarity index 86% rename from python/src/lance_namespace_impls/hive.py rename to python/src/lance_namespace_impls/hive2.py index 28065d3..e2d93b0 100644 --- a/python/src/lance_namespace_impls/hive.py +++ b/python/src/lance_namespace_impls/hive2.py @@ -336,27 +336,26 @@ def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceRe raise def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: - """Drop a database from the Hive Metastore.""" + """Drop a database from the Hive Metastore. Only RESTRICT mode is supported.""" try: # Cannot drop root namespace if self._is_root_namespace(request.id): raise ValueError("Cannot drop root namespace") - + if len(request.id) != 1: raise ValueError(f"Invalid namespace identifier: {request.id}") - + database_name = request.id[0] - + with self.client as client: - # Check if database is empty + # Check if database is empty (RESTRICT mode only) tables = client.get_all_tables(database_name) - cascade = request.behavior == "CASCADE" if request.behavior else False - if tables and not cascade: + if tables: raise ValueError(f"Namespace {request.id} is not empty") - + # Drop database - client.drop_database(database_name, deleteData=True, cascade=cascade) - + client.drop_database(database_name, deleteData=True, cascade=False) + return DropNamespaceResponse() except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): @@ -422,47 +421,31 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: raise def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: - """Describe a table in the Hive Metastore.""" + """Describe a table in the Hive Metastore. + + Only load_detailed_metadata=false is supported. Returns location and storage_options only. + """ try: database, table_name = self._normalize_identifier(request.id) - + with self.client as client: table = client.get_table(database, table_name) - + # Check if it's a Lance table (case insensitive) if not table.parameters: raise ValueError(f"Table {request.id} is not a Lance table") table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() if table_type != LANCE_TABLE_FORMAT: raise ValueError(f"Table {request.id} is not a Lance table") - + # Get table location location = table.sd.location if table.sd else None if not location: raise ValueError(f"Table {request.id} has no location") - - # Build properties from Hive metadata - properties = {} - if table.parameters: - properties.update(table.parameters) - if table.owner: - properties["owner"] = table.owner - - # Get version from table parameters if available - version = None - if table.parameters and VERSION_KEY in table.parameters: - try: - version = int(table.parameters[VERSION_KEY]) - except (ValueError, TypeError): - pass - - # Note: We don't load the Lance dataset here, just return Hive metadata - # Schema will be None as we're not opening the dataset + return DescribeTableResponse( - var_schema=None, location=location, - version=version, - properties=properties + storage_options=self.config.storage_options ) except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): @@ -581,30 +564,15 @@ def table_exists(self, request: TableExistsRequest) -> None: raise def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table from the Hive Metastore.""" - try: - database, table_name = self._normalize_identifier(request.id) - - with self.client as client: - # Get table to check if it's a Lance table - table = client.get_table(database, table_name) - - # Check if it's a Lance table (case insensitive) - if not table.parameters: - raise ValueError(f"Table {request.id} is not a Lance table") - table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() - if table_type != LANCE_TABLE_FORMAT: - raise ValueError(f"Table {request.id} is not a Lance table") - - # Drop the table (always delete data for Lance tables) - client.drop_table(database, table_name, deleteData=True) - - return DropTableResponse() - except Exception as e: - if NoSuchObjectException and isinstance(e, NoSuchObjectException): - raise ValueError(f"Table {request.id} does not exist") - logger.error(f"Failed to drop table {request.id}: {e}") - raise + """Drop a table from the Hive Metastore. + + This operation is not supported. Use deregister_table to remove table metadata, + then use Lance SDK to delete the actual table data if needed. + """ + raise NotImplementedError( + "drop_table is not supported. Use deregister_table to remove table metadata, " + "then use Lance SDK to delete the actual table data if needed." + ) def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableResponse: """Deregister a table from the Hive Metastore without deleting data.""" @@ -635,52 +603,15 @@ def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableRe raise def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: - """Create a new Lance table and register it in the Hive Metastore.""" - try: - database, table_name = self._normalize_identifier(request.id) - - if not request_data: - raise ValueError("Request data (Arrow IPC stream) is required for create_table") - - # Determine table location - location = request.location - if not location: - location = self._get_table_location(database, table_name) - - # Extract table from Arrow IPC stream - try: - reader = pa.ipc.open_stream(request_data) - table = reader.read_all() - except Exception as e: - raise ValueError(f"Invalid Arrow IPC stream: {e}") - - # Create Lance dataset - if request.mode == "create": - # Check if dataset already exists - if os.path.exists(location): - raise ValueError(f"Table {request.id} already exists at {location}") - dataset = lance.write_dataset(table, location) - elif request.mode == "create_or_replace": - dataset = lance.write_dataset(table, location, mode="overwrite") - else: - raise ValueError(f"Unsupported create mode: {request.mode}") - - # Register in Hive Metastore - register_request = RegisterTableRequest( - id=request.id, - location=location, - properties=request.properties - ) - self.register_table(register_request) - - return CreateTableResponse( - id=request.id, - location=location, - version=dataset.version - ) - except Exception as e: - logger.error(f"Failed to create table {request.id}: {e}") - raise + """Create a new Lance table and register it in the Hive Metastore. + + This operation is not supported. Use create_empty_table to declare table metadata, + then use Lance SDK to create the actual table data. + """ + raise NotImplementedError( + "create_table is not supported. Use create_empty_table to declare table metadata, " + "then use Lance SDK to create the actual table data." + ) def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: """Create an empty table (metadata only) in Hive metastore.""" diff --git a/python/src/lance_namespace_impls/hive3.py b/python/src/lance_namespace_impls/hive3.py new file mode 100644 index 0000000..7e51b5d --- /dev/null +++ b/python/src/lance_namespace_impls/hive3.py @@ -0,0 +1,763 @@ +""" +Lance Hive3 Namespace implementation using Hive 3.x Metastore. + +This module provides integration with Apache Hive 3.x Metastore for managing Lance tables. +Hive3 supports a 3-level namespace hierarchy: catalog > database > table. + +Installation: + pip install 'lance-namespace[hive3]' + +Usage: + from lance_namespace import connect + + # Connect to Hive 3.x Metastore + namespace = connect("hive3", { + "uri": "thrift://localhost:9083", + "root": "/my/dir", # Or "s3://bucket/prefix" + "ugi": "user:group1,group2" # Optional user/group info + }) + + # List catalogs (root level) + from lance_namespace import ListNamespacesRequest + response = namespace.list_namespaces(ListNamespacesRequest()) + + # List databases in a catalog + response = namespace.list_namespaces(ListNamespacesRequest(id=["my_catalog"])) + + # Register existing Lance table (3-level: catalog.database.table) + from lance_namespace import RegisterTableRequest + request = RegisterTableRequest( + id=["my_catalog", "my_database", "my_table"], + location="/path/to/lance/table" + ) + response = namespace.register_table(request) + +Configuration Properties: + uri (str): Hive Metastore Thrift URI (e.g., "thrift://localhost:9083") + root (str): Storage root location of the lakehouse (default: current working directory) + ugi (str): Optional User Group Information for authentication (format: "user:group1,group2") + client.pool-size (int): Size of the HMS client connection pool (default: 3) + storage.* (str): Additional storage configurations +""" +from typing import Dict, List, Optional, Any +from urllib.parse import urlparse +import os +import logging + +try: + from hive_metastore.ThriftHiveMetastore import Client + from hive_metastore.ttypes import ( + Database as HiveDatabase, + Table as HiveTable, + StorageDescriptor, + SerDeInfo, + FieldSchema, + NoSuchObjectException, + AlreadyExistsException, + InvalidOperationException, + MetaException, + ) + from thrift.protocol import TBinaryProtocol + from thrift.transport import TSocket, TTransport + HIVE_AVAILABLE = True +except ImportError: + HIVE_AVAILABLE = False + Client = None + HiveDatabase = None + HiveTable = None + StorageDescriptor = None + SerDeInfo = None + FieldSchema = None + NoSuchObjectException = None + AlreadyExistsException = None + InvalidOperationException = None + MetaException = None + +import lance +import pyarrow as pa + +from lance.namespace import LanceNamespace +from lance_namespace_urllib3_client.models import ( + ListNamespacesRequest, + ListNamespacesResponse, + DescribeNamespaceRequest, + DescribeNamespaceResponse, + CreateNamespaceRequest, + CreateNamespaceResponse, + DropNamespaceRequest, + DropNamespaceResponse, + NamespaceExistsRequest, + ListTablesRequest, + ListTablesResponse, + CreateTableRequest, + CreateTableResponse, + CreateEmptyTableRequest, + CreateEmptyTableResponse, + DropTableRequest, + DropTableResponse, + DescribeTableRequest, + DescribeTableResponse, + RegisterTableRequest, + RegisterTableResponse, + DeregisterTableRequest, + DeregisterTableResponse, + TableExistsRequest, +) + +logger = logging.getLogger(__name__) + +TABLE_TYPE_KEY = "table_type" +LANCE_TABLE_FORMAT = "lance" +MANAGED_BY_KEY = "managed_by" +VERSION_KEY = "version" +EXTERNAL_TABLE = "EXTERNAL_TABLE" +DEFAULT_CATALOG = "hive" + + +class Hive3MetastoreClient: + """Helper class to manage Hive 3.x Metastore client connections.""" + + def __init__(self, uri: str, ugi: Optional[str] = None): + if not HIVE_AVAILABLE: + raise ImportError( + "Hive dependencies not installed. Please install with: " + "pip install 'lance-namespace[hive3]'" + ) + + self._uri = uri + self._ugi = ugi.split(":") if ugi else None + self._transport = None + self._client = None + self._init_client() + + def _init_client(self): + """Initialize the Thrift client connection.""" + url_parts = urlparse(self._uri) + socket = TSocket.TSocket(url_parts.hostname, url_parts.port or 9083) + self._transport = TTransport.TBufferedTransport(socket) + protocol = TBinaryProtocol.TBinaryProtocol(self._transport) + self._client = Client(protocol) + + if not self._transport.isOpen(): + self._transport.open() + + if self._ugi: + self._client.set_ugi(*self._ugi) + + def __enter__(self): + """Enter context manager.""" + if not self._transport or not self._transport.isOpen(): + self._init_client() + return self._client + + def __exit__(self, exc_type, exc_val, exc_tb): + """Exit context manager.""" + if self._transport and self._transport.isOpen(): + self._transport.close() + + def close(self): + """Close the client connection.""" + if self._transport and self._transport.isOpen(): + self._transport.close() + + +class Hive3Namespace(LanceNamespace): + """Lance Hive3 Namespace implementation using Hive 3.x Metastore. + + Supports 3-level namespace hierarchy: catalog > database > table. + """ + + def __init__(self, **properties): + """Initialize the Hive3 namespace. + + Args: + uri: The Hive Metastore URI (e.g., "thrift://localhost:9083") + root: Storage root location (optional) + ugi: User Group Information for authentication (optional) + client.pool-size: Size of the HMS client connection pool (optional, default: 3) + storage.*: Additional storage configurations + **properties: Additional configuration properties + """ + if not HIVE_AVAILABLE: + raise ImportError( + "Hive dependencies not installed. Please install with: " + "pip install 'lance-namespace[hive3]'" + ) + + self.uri = properties.get("uri", "thrift://localhost:9083") + self.ugi = properties.get("ugi") + self.root = properties.get("root", os.getcwd()) + self.pool_size = int(properties.get("client.pool-size", "3")) + self.storage_properties = {k[8:]: v for k, v in properties.items() if k.startswith("storage.")} + + self._properties = properties.copy() + self._client = None + + def namespace_id(self) -> str: + """Return a human-readable unique identifier for this namespace instance.""" + return f"Hive3Namespace {{ uri: {self.uri!r} }}" + + @property + def client(self): + """Get the Hive client, initializing it if necessary.""" + if self._client is None: + self._client = Hive3MetastoreClient(self.uri, self.ugi) + return self._client + + def _normalize_identifier(self, identifier: List[str]) -> tuple: + """Normalize identifier to (catalog, database, table) tuple.""" + if len(identifier) == 1: + return (DEFAULT_CATALOG, "default", identifier[0]) + elif len(identifier) == 2: + return (DEFAULT_CATALOG, identifier[0], identifier[1]) + elif len(identifier) == 3: + return (identifier[0], identifier[1], identifier[2]) + else: + raise ValueError(f"Invalid identifier: {identifier}") + + def _is_root_namespace(self, identifier: Optional[List[str]]) -> bool: + """Check if the identifier refers to the root namespace.""" + return not identifier or len(identifier) == 0 + + def _get_table_location(self, catalog: str, database: str, table: str) -> str: + """Get the location for a table.""" + return os.path.join(self.root, database, f"{table}.lance") + + def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: + """List namespaces at the given level. + + - Root level: lists catalogs + - Catalog level: lists databases in that catalog + """ + try: + ns_id = request.id if request.id else [] + + if self._is_root_namespace(ns_id): + # List catalogs + with self.client as client: + # Try to get catalogs if supported (Hive 3.x) + try: + catalogs = client.get_catalogs().names if hasattr(client, 'get_catalogs') else [] + except Exception: + # Fall back to default catalog + catalogs = [DEFAULT_CATALOG] + return ListNamespacesResponse(namespaces=catalogs) + + elif len(ns_id) == 1: + # List databases in catalog + catalog = ns_id[0].lower() + with self.client as client: + try: + databases = client.get_all_databases() + except Exception: + databases = [] + # Exclude 'default' database from list + namespaces = [db for db in databases if db != "default"] + return ListNamespacesResponse(namespaces=namespaces) + + else: + # 2+ level namespaces don't have children + return ListNamespacesResponse(namespaces=[]) + + except Exception as e: + logger.error(f"Failed to list namespaces: {e}") + raise + + def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + """Describe a namespace (catalog or database).""" + try: + if self._is_root_namespace(request.id): + properties = { + "location": self.root, + "description": "Root namespace (Hive 3.x Metastore)" + } + if self.ugi: + properties["ugi"] = self.ugi + return DescribeNamespaceResponse(properties=properties) + + if len(request.id) == 1: + # Describe catalog + catalog_name = request.id[0].lower() + properties = { + "description": f"Catalog: {catalog_name}", + "catalog.location.uri": os.path.join(self.root, catalog_name) + } + return DescribeNamespaceResponse(properties=properties) + + elif len(request.id) == 2: + # Describe database + catalog_name = request.id[0].lower() + database_name = request.id[1].lower() + + with self.client as client: + database = client.get_database(database_name) + + properties = {} + if database.description: + properties["comment"] = database.description + if database.ownerName: + properties["owner"] = database.ownerName + if database.locationUri: + properties["location"] = database.locationUri + if database.parameters: + properties.update(database.parameters) + + return DescribeNamespaceResponse(properties=properties) + else: + raise ValueError(f"Invalid namespace identifier: {request.id}") + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Namespace {request.id} does not exist") + logger.error(f"Failed to describe namespace {request.id}: {e}") + raise + + def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + """Create a new namespace (catalog or database).""" + try: + if self._is_root_namespace(request.id): + raise ValueError("Root namespace already exists") + + mode = request.mode.lower() if request.mode else "create" + + if len(request.id) == 1: + # Create catalog (Hive 3.x) + # Note: Python Hive client may not support catalog creation + catalog_name = request.id[0].lower() + logger.warning(f"Catalog creation may not be supported: {catalog_name}") + return CreateNamespaceResponse() + + elif len(request.id) == 2: + # Create database + catalog_name = request.id[0].lower() + database_name = request.id[1].lower() + + if not HiveDatabase: + raise ImportError("Hive dependencies not available") + + database = HiveDatabase() + database.name = database_name + database.description = request.properties.get("comment", "") if request.properties else "" + database.ownerName = request.properties.get("owner", os.getenv("USER", "")) if request.properties else os.getenv("USER", "") + database.locationUri = request.properties.get( + "location", + os.path.join(self.root, database_name) + ) if request.properties else os.path.join(self.root, database_name) + + if request.properties: + database.parameters = { + k: v for k, v in request.properties.items() + if k not in ["comment", "owner", "location"] + } + + with self.client as client: + try: + client.create_database(database) + except AlreadyExistsException: + if mode == "create": + raise ValueError(f"Namespace {request.id} already exists") + elif mode in ("exist_ok", "existok"): + pass # OK to exist + elif mode == "overwrite": + client.drop_database(database_name, deleteData=True, cascade=True) + client.create_database(database) + + return CreateNamespaceResponse() + else: + raise ValueError(f"Invalid namespace identifier: {request.id}") + + except Exception as e: + if AlreadyExistsException and isinstance(e, AlreadyExistsException): + raise ValueError(f"Namespace {request.id} already exists") + logger.error(f"Failed to create namespace {request.id}: {e}") + raise + + def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: + """Drop a namespace (catalog or database). Only RESTRICT mode is supported.""" + try: + if self._is_root_namespace(request.id): + raise ValueError("Cannot drop root namespace") + + if len(request.id) == 1: + # Drop catalog (Hive 3.x) + catalog_name = request.id[0].lower() + logger.warning(f"Catalog drop may not be supported: {catalog_name}") + return DropNamespaceResponse() + + elif len(request.id) == 2: + # Drop database + database_name = request.id[1].lower() + + with self.client as client: + # Check if database is empty (RESTRICT mode only) + tables = client.get_all_tables(database_name) + if tables: + raise ValueError(f"Namespace {request.id} is not empty") + + client.drop_database(database_name, deleteData=True, cascade=False) + + return DropNamespaceResponse() + else: + raise ValueError(f"Invalid namespace identifier: {request.id}") + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Namespace {request.id} does not exist") + logger.error(f"Failed to drop namespace {request.id}: {e}") + raise + + def namespace_exists(self, request: NamespaceExistsRequest) -> None: + """Check if a namespace exists.""" + try: + if self._is_root_namespace(request.id): + return + + if len(request.id) == 1: + # Check catalog exists + # For simplicity, assume standard catalogs exist + return + + elif len(request.id) == 2: + # Check database exists + database_name = request.id[1].lower() + + with self.client as client: + client.get_database(database_name) + else: + raise ValueError(f"Invalid namespace identifier: {request.id}") + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Namespace {request.id} does not exist") + logger.error(f"Failed to check namespace existence {request.id}: {e}") + raise + + def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: + """List tables in a database.""" + try: + if self._is_root_namespace(request.id) or len(request.id) < 2: + return ListTablesResponse(tables=[]) + + catalog_name = request.id[0].lower() + database_name = request.id[1].lower() + + with self.client as client: + table_names = client.get_all_tables(database_name) + + # Filter for Lance tables + tables = [] + for table_name in table_names: + try: + table = client.get_table(database_name, table_name) + if table.parameters: + table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + if table_type == LANCE_TABLE_FORMAT: + tables.append(table_name) + except Exception: + continue + + return ListTablesResponse(tables=tables) + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Namespace {request.id} does not exist") + logger.error(f"Failed to list tables in namespace {request.id}: {e}") + raise + + def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: + """Describe a table. + + Only load_detailed_metadata=false is supported. Returns location and storage_options only. + """ + try: + catalog, database, table_name = self._normalize_identifier(request.id) + + with self.client as client: + table = client.get_table(database, table_name) + + if not table.parameters: + raise ValueError(f"Table {request.id} is not a Lance table") + table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + if table_type != LANCE_TABLE_FORMAT: + raise ValueError(f"Table {request.id} is not a Lance table") + + location = table.sd.location if table.sd else None + if not location: + raise ValueError(f"Table {request.id} has no location") + + return DescribeTableResponse( + location=location, + storage_options=self.config.storage_options + ) + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Table {request.id} does not exist") + logger.error(f"Failed to describe table {request.id}: {e}") + raise + + def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: + """Register an existing Lance table in the Hive Metastore.""" + try: + catalog, database, table_name = self._normalize_identifier(request.id) + + managed_by = request.properties.get(MANAGED_BY_KEY, "storage") if request.properties else "storage" + + dataset = lance.dataset(request.location) + schema = dataset.schema + + version = None + if managed_by == "impl": + version = request.properties.get(VERSION_KEY) if request.properties else None + if version is None: + version = str(dataset.version) + + if not HiveTable: + raise ImportError("Hive dependencies not available") + + hive_table = HiveTable() + hive_table.dbName = database + hive_table.tableName = table_name + hive_table.owner = request.properties.get("owner", os.getenv("USER", "")) if request.properties else os.getenv("USER", "") + + import time + current_time = int(time.time()) + try: + hive_table.createTime = int(os.path.getctime(request.location)) + hive_table.lastAccessTime = int(os.path.getatime(request.location)) + except (OSError, FileNotFoundError): + hive_table.createTime = current_time + hive_table.lastAccessTime = current_time + hive_table.tableType = EXTERNAL_TABLE + + if not StorageDescriptor: + raise ImportError("Hive dependencies not available") + sd = StorageDescriptor() + sd.location = request.location + sd.inputFormat = "com.lancedb.lance.mapred.LanceInputFormat" + sd.outputFormat = "com.lancedb.lance.mapred.LanceOutputFormat" + sd.compressed = False + sd.cols = self._pyarrow_schema_to_hive_fields(schema) + + if not SerDeInfo: + raise ImportError("Hive dependencies not available") + serde = SerDeInfo() + serde.serializationLib = "com.lancedb.lance.mapred.LanceSerDe" + sd.serdeInfo = serde + + hive_table.sd = sd + + hive_table.parameters = { + TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, + MANAGED_BY_KEY: managed_by, + } + + if managed_by == "impl" and version is not None: + hive_table.parameters[VERSION_KEY] = version + + if request.properties: + for k, v in request.properties.items(): + if k not in [TABLE_TYPE_KEY, MANAGED_BY_KEY, VERSION_KEY]: + hive_table.parameters[k] = v + + with self.client as client: + client.create_table(hive_table) + + return RegisterTableResponse( + location=request.location, + properties=request.properties + ) + + except Exception as e: + if AlreadyExistsException and isinstance(e, AlreadyExistsException): + raise ValueError(f"Table {request.id} already exists") + logger.error(f"Failed to register table {request.id}: {e}") + raise + + def table_exists(self, request: TableExistsRequest) -> None: + """Check if a table exists.""" + try: + catalog, database, table_name = self._normalize_identifier(request.id) + + with self.client as client: + table = client.get_table(database, table_name) + + if not table.parameters: + raise ValueError(f"Table {request.id} is not a Lance table") + table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + if table_type != LANCE_TABLE_FORMAT: + raise ValueError(f"Table {request.id} is not a Lance table") + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Table {request.id} does not exist") + logger.error(f"Failed to check table existence {request.id}: {e}") + raise + + def drop_table(self, request: DropTableRequest) -> DropTableResponse: + """Drop a table from the Hive Metastore. + + This operation is not supported. Use deregister_table to remove table metadata, + then use Lance SDK to delete the actual table data if needed. + """ + raise NotImplementedError( + "drop_table is not supported. Use deregister_table to remove table metadata, " + "then use Lance SDK to delete the actual table data if needed." + ) + + def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableResponse: + """Deregister a table without deleting data.""" + try: + catalog, database, table_name = self._normalize_identifier(request.id) + + with self.client as client: + table = client.get_table(database, table_name) + + if not table.parameters: + raise ValueError(f"Table {request.id} is not a Lance table") + table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + if table_type != LANCE_TABLE_FORMAT: + raise ValueError(f"Table {request.id} is not a Lance table") + + location = table.sd.location if table.sd else None + + client.drop_table(database, table_name, deleteData=False) + + return DeregisterTableResponse(location=location) + + except Exception as e: + if NoSuchObjectException and isinstance(e, NoSuchObjectException): + raise ValueError(f"Table {request.id} does not exist") + logger.error(f"Failed to deregister table {request.id}: {e}") + raise + + def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: + """Create a new Lance table and register it. + + This operation is not supported. Use create_empty_table to declare table metadata, + then use Lance SDK to create the actual table data. + """ + raise NotImplementedError( + "create_table is not supported. Use create_empty_table to declare table metadata, " + "then use Lance SDK to create the actual table data." + ) + + def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + """Create an empty table (metadata only).""" + try: + catalog, database, table_name = self._normalize_identifier(request.id) + + location = request.location + if not location: + location = self._get_table_location(catalog, database, table_name) + + if not FieldSchema: + raise ImportError("Hive dependencies not available") + + fields = [ + FieldSchema( + name='__placeholder_id', + type='bigint', + comment='Placeholder column' + ) + ] + + storage_descriptor = StorageDescriptor( + cols=fields, + location=location, + inputFormat='org.apache.hadoop.mapred.TextInputFormat', + outputFormat='org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat', + serdeInfo=SerDeInfo( + serializationLib='org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' + ) + ) + + parameters = { + TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, + MANAGED_BY_KEY: "storage", + 'empty_table': 'true', + } + + if request.properties: + parameters.update(request.properties) + + hive_table = HiveTable( + tableName=table_name, + dbName=database, + sd=storage_descriptor, + parameters=parameters, + tableType='EXTERNAL_TABLE' + ) + + with self.client as client: + client.create_table(hive_table) + + return CreateEmptyTableResponse(location=location) + + except AlreadyExistsException: + raise ValueError(f"Table {request.id} already exists") + except Exception as e: + logger.error(f"Failed to create empty table {request.id}: {e}") + raise + + def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema]: + """Convert PyArrow schema to Hive field schemas.""" + fields = [] + for field in schema: + hive_type = self._pyarrow_type_to_hive_type(field.type) + if not FieldSchema: + raise ImportError("Hive dependencies not available") + hive_field = FieldSchema( + name=field.name, + type=hive_type, + comment="" + ) + fields.append(hive_field) + return fields + + def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: + """Convert PyArrow data type to Hive type string.""" + if pa.types.is_boolean(dtype): + return "boolean" + elif pa.types.is_int8(dtype): + return "tinyint" + elif pa.types.is_int16(dtype): + return "smallint" + elif pa.types.is_int32(dtype): + return "int" + elif pa.types.is_int64(dtype): + return "bigint" + elif pa.types.is_float32(dtype): + return "float" + elif pa.types.is_float64(dtype): + return "double" + elif pa.types.is_string(dtype): + return "string" + elif pa.types.is_binary(dtype): + return "binary" + elif pa.types.is_timestamp(dtype): + return "timestamp" + elif pa.types.is_date32(dtype) or pa.types.is_date64(dtype): + return "date" + elif pa.types.is_list(dtype): + inner_type = self._pyarrow_type_to_hive_type(dtype.value_type) + return f"array<{inner_type}>" + elif pa.types.is_struct(dtype): + field_strs = [] + for i in range(dtype.num_fields): + field = dtype.field(i) + field_type = self._pyarrow_type_to_hive_type(field.type) + field_strs.append(f"{field.name}:{field_type}") + return f"struct<{','.join(field_strs)}>" + else: + return "string" + + def __getstate__(self): + """Prepare instance for pickling.""" + state = self.__dict__.copy() + state['_client'] = None + return state + + def __setstate__(self, state): + """Restore instance from pickled state.""" + self.__dict__.update(state) diff --git a/python/src/lance_namespace_impls/iceberg.py b/python/src/lance_namespace_impls/iceberg.py index 69d389c..e2cb1a8 100644 --- a/python/src/lance_namespace_impls/iceberg.py +++ b/python/src/lance_namespace_impls/iceberg.py @@ -2,41 +2,47 @@ Iceberg REST Catalog namespace implementation for Lance. """ -import json import logging -import os -from typing import Dict, List, Optional, Any -from dataclasses import dataclass, field -import urllib3 import urllib.parse +from dataclasses import dataclass +from typing import Any, Dict, List, Optional +from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( - ListNamespacesRequest, - ListNamespacesResponse, - DescribeNamespaceRequest, - DescribeNamespaceResponse, + CreateEmptyTableRequest, + CreateEmptyTableResponse, CreateNamespaceRequest, CreateNamespaceResponse, + DeregisterTableRequest, + DeregisterTableResponse, + DescribeNamespaceRequest, + DescribeNamespaceResponse, + DescribeTableRequest, + DescribeTableResponse, DropNamespaceRequest, DropNamespaceResponse, - NamespaceExistsRequest, + ListNamespacesRequest, + ListNamespacesResponse, ListTablesRequest, ListTablesResponse, - DescribeTableRequest, - DescribeTableResponse, + NamespaceExistsRequest, TableExistsRequest, - DropTableRequest, - DropTableResponse, - CreateEmptyTableRequest, - CreateEmptyTableResponse, ) -from lance.namespace import LanceNamespace - +from lance_namespace_impls.rest_client import ( + RestClient, + RestClientException, + InternalException, + InvalidInputException, + NamespaceAlreadyExistsException, + NamespaceNotFoundException, + TableAlreadyExistsException, + TableNotFoundException, +) logger = logging.getLogger(__name__) -NAMESPACE_SEPARATOR = '\x1F' +NAMESPACE_SEPARATOR = "\x1F" @dataclass @@ -79,130 +85,18 @@ def __init__(self, properties: Dict[str, str]): def get_full_api_url(self) -> str: """Get the full API URL with prefix.""" - base = self.endpoint.rstrip('/') + base = self.endpoint.rstrip("/") if self.prefix: return f"{base}/{self.prefix}" return base -class RestClient: - """Simple REST client for Iceberg REST Catalog API.""" - - def __init__(self, base_url: str, headers: Optional[Dict[str, str]] = None, - connect_timeout: int = 10, read_timeout: int = 30, max_retries: int = 3): - self.base_url = base_url.rstrip('/') - self.headers = headers or {} - self.headers['Content-Type'] = 'application/json' - self.headers['Accept'] = 'application/json' - - timeout = urllib3.Timeout(connect=connect_timeout/1000, read=read_timeout/1000) - self.http = urllib3.PoolManager( - timeout=timeout, - retries=urllib3.Retry(total=max_retries, backoff_factor=0.3) - ) - - def _make_request(self, method: str, path: str, params: Optional[Dict[str, str]] = None, - body: Optional[Any] = None) -> Any: - """Make HTTP request to Iceberg API.""" - url = f"{self.base_url}{path}" - - if params: - query_string = urllib.parse.urlencode(params) - url = f"{url}?{query_string}" - - body_data = None - if body is not None: - body_data = json.dumps(body).encode('utf-8') - - try: - response = self.http.request( - method, - url, - headers=self.headers, - body=body_data - ) - - if response.status >= 400: - raise RestClientException(response.status, response.data.decode('utf-8')) - - if response.data: - return json.loads(response.data.decode('utf-8')) - return None - - except urllib3.exceptions.HTTPError as e: - raise RestClientException(500, str(e)) - - def get(self, path: str, params: Optional[Dict[str, str]] = None) -> Any: - """Make GET request.""" - return self._make_request('GET', path, params=params) - - def post(self, path: str, body: Any) -> Any: - """Make POST request.""" - return self._make_request('POST', path, body=body) - - def delete(self, path: str, params: Optional[Dict[str, str]] = None) -> None: - """Make DELETE request.""" - self._make_request('DELETE', path, params=params) - - def close(self): - """Close the HTTP connection pool.""" - self.http.clear() - - -class RestClientException(Exception): - """Exception raised by REST client.""" - - def __init__(self, status_code: int, response_body: str): - self.status_code = status_code - self.response_body = response_body - super().__init__(f"HTTP {status_code}: {response_body}") - - -class LanceNamespaceException(Exception): - """Exception for Lance namespace operations.""" - - def __init__(self, status_code: int, message: str): - self.status_code = status_code - super().__init__(message) - - @classmethod - def not_found(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a not found exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(404, full_message) - - @classmethod - def bad_request(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a bad request exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(400, full_message) - - @classmethod - def conflict(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a conflict exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(409, full_message) - - def create_dummy_schema() -> Dict[str, Any]: """Create a dummy Iceberg schema with a single string column.""" return { "type": "struct", "schema-id": 0, - "fields": [ - { - "id": 1, - "name": "dummy", - "required": False, - "type": "string" - } - ] + "fields": [{"id": 1, "name": "dummy", "required": False, "type": "string"}], } @@ -218,19 +112,21 @@ def __init__(self, **properties): headers = {} if self.config.auth_token: - headers['Authorization'] = f"Bearer {self.config.auth_token}" + headers["Authorization"] = f"Bearer {self.config.auth_token}" if self.config.warehouse: - headers['X-Iceberg-Access-Delegation'] = 'vended-credentials' + headers["X-Iceberg-Access-Delegation"] = "vended-credentials" self.rest_client = RestClient( base_url=self.config.get_full_api_url(), headers=headers, connect_timeout=self.config.connect_timeout, read_timeout=self.config.read_timeout, - max_retries=self.config.max_retries + max_retries=self.config.max_retries, ) - logger.info(f"Initialized Iceberg namespace with endpoint: {self.config.endpoint}") + logger.info( + f"Initialized Iceberg namespace with endpoint: {self.config.endpoint}" + ) def namespace_id(self) -> str: """Return a human-readable unique identifier for this namespace instance.""" @@ -238,9 +134,9 @@ def namespace_id(self) -> str: def _encode_namespace(self, namespace: List[str]) -> str: """Encode namespace for URL path.""" - encoded_parts = [urllib.parse.quote(s, safe='') for s in namespace] + encoded_parts = [urllib.parse.quote(s, safe="") for s in namespace] joined = NAMESPACE_SEPARATOR.join(encoded_parts) - return urllib.parse.quote(joined, safe='') + return urllib.parse.quote(joined, safe="") def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: """List namespaces.""" @@ -250,86 +146,85 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo params = {} if ns_id: parent = self._encode_namespace(ns_id) - params['parent'] = parent + params["parent"] = parent if request.page_token: - params['pageToken'] = request.page_token + params["pageToken"] = request.page_token - response = self.rest_client.get('/namespaces', params=params if params else None) + response = self.rest_client.get( + "/namespaces", params=params if params else None + ) namespaces = [] - if response and 'namespaces' in response: - for ns in response['namespaces']: + if response and "namespaces" in response: + for ns in response["namespaces"]: if ns: namespaces.append(ns[-1]) namespaces = sorted(set(namespaces)) - result = ListNamespacesResponse() - result.namespaces = namespaces - return result + return ListNamespacesResponse(namespaces=namespaces) + except RestClientException as e: + raise InternalException(f"Failed to list namespaces: {e}") except Exception as e: - if isinstance(e, LanceNamespaceException): - raise - raise LanceNamespaceException(500, f"Failed to list namespaces: {e}") + raise InternalException(f"Failed to list namespaces: {e}") - def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: """Create a new namespace.""" ns_id = self._parse_identifier(request.id) if not ns_id: - raise ValueError("Namespace must have at least one level") + raise InvalidInputException("Namespace must have at least one level") try: - create_request = { - "namespace": ns_id, - "properties": request.properties or {} - } + create_request = {"namespace": ns_id, "properties": request.properties or {}} + + response = self.rest_client.post("/namespaces", create_request) - response = self.rest_client.post('/namespaces', create_request) + logger.info(f"Created namespace: {'.'.join(ns_id)}") - result = CreateNamespaceResponse() - result.properties = response.get('properties') if response else None - return result + properties = response.get("properties") if response else {} + return CreateNamespaceResponse(properties=properties) except RestClientException as e: - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Namespace already exists", - "NAMESPACE_EXISTS", - '.'.join(request.id), - e.response_body + if e.is_conflict(): + raise NamespaceAlreadyExistsException( + f"Namespace already exists: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to create namespace: {e}") + raise InternalException(f"Failed to create namespace: {e}") + except (NamespaceAlreadyExistsException, InvalidInputException): + raise except Exception as e: - raise LanceNamespaceException(500, f"Failed to create namespace: {e}") + raise InternalException(f"Failed to create namespace: {e}") - def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: """Describe a namespace.""" ns_id = self._parse_identifier(request.id) if not ns_id: - raise ValueError("Namespace must have at least one level") + raise InvalidInputException("Namespace must have at least one level") try: namespace_path = self._encode_namespace(ns_id) response = self.rest_client.get(f"/namespaces/{namespace_path}") - result = DescribeNamespaceResponse() - result.properties = response.get('properties') if response else None - return result + properties = response.get("properties") if response else {} + return DescribeNamespaceResponse(properties=properties) except RestClientException as e: - if e.status_code == 404: - raise LanceNamespaceException.not_found( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - '.'.join(request.id), - e.response_body + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to describe namespace: {e}") + raise InternalException(f"Failed to describe namespace: {e}") + except (NamespaceNotFoundException, InvalidInputException): + raise except Exception as e: - raise LanceNamespaceException(500, f"Failed to describe namespace: {e}") + raise InternalException(f"Failed to describe namespace: {e}") def namespace_exists(self, request: NamespaceExistsRequest) -> None: """Check if a namespace exists.""" @@ -342,70 +237,79 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse ns_id = self._parse_identifier(request.id) if not ns_id: - raise ValueError("Namespace must have at least one level") + raise InvalidInputException("Namespace must have at least one level") try: namespace_path = self._encode_namespace(ns_id) self.rest_client.delete(f"/namespaces/{namespace_path}") - return DropNamespaceResponse() + logger.info(f"Dropped namespace: {'.'.join(ns_id)}") + + return DropNamespaceResponse(properties={}) except RestClientException as e: - if e.status_code == 404: - return DropNamespaceResponse() - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Namespace not empty", - "NAMESPACE_NOT_EMPTY", - '.'.join(request.id), - e.response_body + if e.is_not_found(): + return DropNamespaceResponse(properties={}) + if e.is_conflict(): + raise InternalException( + f"Namespace not empty: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to drop namespace: {e}") + raise InternalException(f"Failed to drop namespace: {e}") + except InvalidInputException: + raise except Exception as e: - raise LanceNamespaceException(500, f"Failed to drop namespace: {e}") + raise InternalException(f"Failed to drop namespace: {e}") def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a namespace.""" ns_id = self._parse_identifier(request.id) if not ns_id: - raise ValueError("Namespace must have at least one level") + raise InvalidInputException("Namespace must have at least one level") try: namespace_path = self._encode_namespace(ns_id) params = {} if request.page_token: - params['pageToken'] = request.page_token + params["pageToken"] = request.page_token response = self.rest_client.get( f"/namespaces/{namespace_path}/tables", - params=params if params else None + params=params if params else None, ) tables = [] - if response and 'identifiers' in response: - for table_id in response['identifiers']: - table_name = table_id.get('name') + if response and "identifiers" in response: + for table_id in response["identifiers"]: + table_name = table_id.get("name") if table_name and self._is_lance_table(ns_id, table_name): tables.append(table_name) tables = sorted(set(tables)) - result = ListTablesResponse() - result.tables = tables - return result + return ListTablesResponse(tables=tables) + except RestClientException as e: + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(ns_id)}" + ) + raise InternalException(f"Failed to list tables: {e}") + except (NamespaceNotFoundException, InvalidInputException): + raise except Exception as e: - if isinstance(e, LanceNamespaceException): - raise - raise LanceNamespaceException(500, f"Failed to list tables: {e}") + raise InternalException(f"Failed to list tables: {e}") - def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: """Create an empty table (metadata only operation).""" table_id = self._parse_identifier(request.id) if len(table_id) < 2: - raise ValueError("Table identifier must have at least namespace and table name") + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) namespace = table_id[:-1] table_name = table_id[-1] @@ -415,105 +319,91 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab if not table_path: table_path = f"{self.config.root}/{'/'.join(namespace)}/{table_name}" - properties = { - self.TABLE_TYPE_KEY: self.TABLE_TYPE_LANCE - } - if request.properties: - properties.update(request.properties) + properties = {self.TABLE_TYPE_KEY: self.TABLE_TYPE_LANCE} create_request = { "name": table_name, "location": table_path, "schema": create_dummy_schema(), - "properties": properties + "properties": properties, } namespace_path = self._encode_namespace(namespace) response = self.rest_client.post( - f"/namespaces/{namespace_path}/tables", - create_request + f"/namespaces/{namespace_path}/tables", create_request ) - result = CreateEmptyTableResponse() - result.location = table_path - if response and 'metadata' in response: - result.properties = response['metadata'].get('properties') - return result + logger.info(f"Created table: {'.'.join(table_id)}") + + return CreateEmptyTableResponse(location=table_path) except RestClientException as e: - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - '.'.join(request.id), - e.response_body + if e.is_conflict(): + raise TableAlreadyExistsException( + f"Table already exists: {'.'.join(request.id)}" ) - if e.status_code == 404: - raise LanceNamespaceException.not_found( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - '.'.join(namespace), - e.response_body + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(namespace)}" ) - raise LanceNamespaceException(500, f"Failed to create empty table: {e}") + raise InternalException(f"Failed to create empty table: {e}") + except ( + TableAlreadyExistsException, + NamespaceNotFoundException, + InvalidInputException, + ): + raise except Exception as e: - raise LanceNamespaceException(500, f"Failed to create empty table: {e}") + raise InternalException(f"Failed to create empty table: {e}") def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table.""" table_id = self._parse_identifier(request.id) if len(table_id) < 2: - raise ValueError("Table identifier must have at least namespace and table name") + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) namespace = table_id[:-1] table_name = table_id[-1] try: namespace_path = self._encode_namespace(namespace) - encoded_table_name = urllib.parse.quote(table_name, safe='') + encoded_table_name = urllib.parse.quote(table_name, safe="") response = self.rest_client.get( f"/namespaces/{namespace_path}/tables/{encoded_table_name}" ) - if not response or 'metadata' not in response: - raise LanceNamespaceException.not_found( - "Table not found", - "TABLE_NOT_FOUND", - '.'.join(request.id), - "No metadata" + if not response or "metadata" not in response: + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" ) - metadata = response['metadata'] - props = metadata.get('properties', {}) + metadata = response["metadata"] + props = metadata.get("properties", {}) - if not props.get(self.TABLE_TYPE_KEY, '').lower() == self.TABLE_TYPE_LANCE.lower(): - raise LanceNamespaceException.bad_request( - "Not a Lance table", - "INVALID_TABLE", - '.'.join(request.id), - "Table is not managed by Lance" + if not props.get(self.TABLE_TYPE_KEY, "").lower() == self.TABLE_TYPE_LANCE.lower(): + raise InvalidInputException( + f"Table {'.'.join(request.id)} is not a Lance table" ) - result = DescribeTableResponse() - result.location = metadata.get('location') - result.properties = props - return result + return DescribeTableResponse( + location=metadata.get("location"), + storage_options=props + ) except RestClientException as e: - if e.status_code == 404: - raise LanceNamespaceException.not_found( - "Table not found", - "TABLE_NOT_FOUND", - '.'.join(request.id), - e.response_body + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to describe table: {e}") + raise InternalException(f"Failed to describe table: {e}") + except (TableNotFoundException, InvalidInputException): + raise except Exception as e: - if isinstance(e, LanceNamespaceException): - raise - raise LanceNamespaceException(500, f"Failed to describe table: {e}") + raise InternalException(f"Failed to describe table: {e}") def table_exists(self, request: TableExistsRequest) -> None: """Check if a table exists.""" @@ -521,47 +411,51 @@ def table_exists(self, request: TableExistsRequest) -> None: describe_request.id = request.id self.describe_table(describe_request) - def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table.""" + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: + """Deregister a table (remove from catalog without deleting data).""" table_id = self._parse_identifier(request.id) if len(table_id) < 2: - raise ValueError("Table identifier must have at least namespace and table name") + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) namespace = table_id[:-1] table_name = table_id[-1] try: namespace_path = self._encode_namespace(namespace) - encoded_table_name = urllib.parse.quote(table_name, safe='') + encoded_table_name = urllib.parse.quote(table_name, safe="") + + response = self.rest_client.get( + f"/namespaces/{namespace_path}/tables/{encoded_table_name}" + ) table_location = None - try: - response = self.rest_client.get( - f"/namespaces/{namespace_path}/tables/{encoded_table_name}" - ) - if response and 'metadata' in response: - table_location = response['metadata'].get('location') - except RestClientException as e: - if e.status_code == 404: - result = DropTableResponse() - result.id = request.id - return result + if response and "metadata" in response: + table_location = response["metadata"].get("location") self.rest_client.delete( f"/namespaces/{namespace_path}/tables/{encoded_table_name}", - params={'purgeRequested': 'false'} + params={"purgeRequested": "false"}, ) - result = DropTableResponse() - result.id = request.id - result.location = table_location - return result + logger.info(f"Deregistered table: {'.'.join(table_id)}") + return DeregisterTableResponse(location=table_location) + + except RestClientException as e: + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to deregister table: {e}") + except (TableNotFoundException, InvalidInputException): + raise except Exception as e: - if isinstance(e, LanceNamespaceException): - raise - raise LanceNamespaceException(500, f"Failed to drop table: {e}") + raise InternalException(f"Failed to deregister table: {e}") def close(self): """Close the namespace connection.""" @@ -576,15 +470,18 @@ def _is_lance_table(self, namespace: List[str], table_name: str) -> bool: """Check if a table is a Lance table.""" try: namespace_path = self._encode_namespace(namespace) - encoded_table_name = urllib.parse.quote(table_name, safe='') + encoded_table_name = urllib.parse.quote(table_name, safe="") response = self.rest_client.get( f"/namespaces/{namespace_path}/tables/{encoded_table_name}" ) - if response and 'metadata' in response: - props = response['metadata'].get('properties', {}) - return props.get(self.TABLE_TYPE_KEY, '').lower() == self.TABLE_TYPE_LANCE.lower() + if response and "metadata" in response: + props = response["metadata"].get("properties", {}) + return ( + props.get(self.TABLE_TYPE_KEY, "").lower() + == self.TABLE_TYPE_LANCE.lower() + ) except Exception as e: logger.debug(f"Failed to check if table is Lance table: {e}") return False diff --git a/python/src/lance_namespace_impls/polaris.py b/python/src/lance_namespace_impls/polaris.py new file mode 100644 index 0000000..4ae373a --- /dev/null +++ b/python/src/lance_namespace_impls/polaris.py @@ -0,0 +1,426 @@ +""" +Polaris Catalog namespace implementation for Lance. +""" + +import logging +from dataclasses import dataclass +from typing import Any, Dict, List, Optional + +from lance.namespace import LanceNamespace +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateEmptyTableResponse, + CreateNamespaceRequest, + CreateNamespaceResponse, + DeregisterTableRequest, + DeregisterTableResponse, + DescribeNamespaceRequest, + DescribeNamespaceResponse, + DescribeTableRequest, + DescribeTableResponse, + DropNamespaceRequest, + DropNamespaceResponse, + ListNamespacesRequest, + ListNamespacesResponse, + ListTablesRequest, + ListTablesResponse, + NamespaceExistsRequest, + TableExistsRequest, +) + +from lance_namespace_impls.rest_client import ( + RestClient, + RestClientException, + InternalException, + InvalidInputException, + NamespaceAlreadyExistsException, + NamespaceNotFoundException, + TableAlreadyExistsException, + TableNotFoundException, +) + +logger = logging.getLogger(__name__) + + +@dataclass +class PolarisNamespaceConfig: + """Configuration for Polaris Catalog namespace.""" + + ENDPOINT = "polaris.endpoint" + AUTH_TOKEN = "polaris.auth_token" + CONNECT_TIMEOUT = "polaris.connect_timeout_millis" + READ_TIMEOUT = "polaris.read_timeout_millis" + MAX_RETRIES = "polaris.max_retries" + ROOT = "polaris.root" + + endpoint: str + auth_token: Optional[str] = None + connect_timeout: int = 10000 + read_timeout: int = 30000 + max_retries: int = 3 + root: str = "/tmp/lance" + + def __init__(self, properties: Dict[str, str]): + self.endpoint = properties.get(self.ENDPOINT) + if not self.endpoint: + raise ValueError(f"Required property {self.ENDPOINT} is not set") + + self.auth_token = properties.get(self.AUTH_TOKEN) + self.connect_timeout = int(properties.get(self.CONNECT_TIMEOUT, "10000")) + self.read_timeout = int(properties.get(self.READ_TIMEOUT, "30000")) + self.max_retries = int(properties.get(self.MAX_RETRIES, "3")) + self.root = properties.get(self.ROOT, "/tmp/lance") + + def get_full_api_url(self) -> str: + """Get the full API URL.""" + return self.endpoint.rstrip("/") + + +class PolarisNamespace(LanceNamespace): + """Polaris Catalog namespace implementation for Lance.""" + + TABLE_FORMAT_LANCE = "lance" + TABLE_TYPE_KEY = "table_type" + + def __init__(self, **properties): + """Initialize Polaris namespace with configuration properties.""" + self.config = PolarisNamespaceConfig(properties) + + headers = {} + if self.config.auth_token: + headers["Authorization"] = f"Bearer {self.config.auth_token}" + + self.rest_client = RestClient( + base_url=self.config.get_full_api_url(), + headers=headers, + connect_timeout=self.config.connect_timeout, + read_timeout=self.config.read_timeout, + max_retries=self.config.max_retries, + ) + + logger.info( + f"Initialized Polaris namespace with endpoint: {self.config.endpoint}" + ) + + def namespace_id(self) -> str: + """Return a human-readable unique identifier for this namespace instance.""" + return f"PolarisNamespace {{ endpoint: {self.config.endpoint!r} }}" + + def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: + """List namespaces.""" + ns_id = self._parse_identifier(request.id) + + try: + if not ns_id: + path = "/namespaces" + else: + parent_path = ".".join(ns_id) + path = f"/namespaces/{parent_path}/namespaces" + + response = self.rest_client.get(path) + + namespaces = [] + if response and "namespaces" in response: + for ns in response["namespaces"]: + if ns: + namespaces.append(".".join(ns)) + + namespaces = sorted(set(namespaces)) + + return ListNamespacesResponse(namespaces=namespaces) + + except RestClientException as e: + raise InternalException(f"Failed to list namespaces: {e}") + except Exception as e: + raise InternalException(f"Failed to list namespaces: {e}") + + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: + """Create a new namespace.""" + ns_id = self._parse_identifier(request.id) + + if not ns_id: + raise InvalidInputException("Namespace must have at least one level") + + try: + create_request = { + "namespace": ns_id, + "properties": request.properties or {}, + } + + response = self.rest_client.post("/namespaces", create_request) + + logger.info(f"Created namespace: {'.'.join(ns_id)}") + + properties = response.get("properties") if response else {} + return CreateNamespaceResponse(properties=properties) + + except RestClientException as e: + if e.is_conflict(): + raise NamespaceAlreadyExistsException( + f"Namespace already exists: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to create namespace: {e}") + except (NamespaceAlreadyExistsException, InvalidInputException): + raise + except Exception as e: + raise InternalException(f"Failed to create namespace: {e}") + + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: + """Describe a namespace.""" + ns_id = self._parse_identifier(request.id) + + if not ns_id: + raise InvalidInputException("Namespace must have at least one level") + + try: + namespace_path = ".".join(ns_id) + response = self.rest_client.get(f"/namespaces/{namespace_path}") + + properties = response.get("properties") if response else {} + return DescribeNamespaceResponse(properties=properties) + + except RestClientException as e: + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to describe namespace: {e}") + except (NamespaceNotFoundException, InvalidInputException): + raise + except Exception as e: + raise InternalException(f"Failed to describe namespace: {e}") + + def namespace_exists(self, request: NamespaceExistsRequest) -> None: + """Check if a namespace exists.""" + describe_request = DescribeNamespaceRequest() + describe_request.id = request.id + self.describe_namespace(describe_request) + + def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: + """Drop a namespace. Only RESTRICT mode is supported.""" + ns_id = self._parse_identifier(request.id) + + if not ns_id: + raise InvalidInputException("Namespace must have at least one level") + + try: + namespace_path = ".".join(ns_id) + self.rest_client.delete(f"/namespaces/{namespace_path}") + + logger.info(f"Dropped namespace: {'.'.join(ns_id)}") + + return DropNamespaceResponse(properties={}) + + except RestClientException as e: + if e.is_not_found(): + return DropNamespaceResponse(properties={}) + raise InternalException(f"Failed to drop namespace: {e}") + except InvalidInputException: + raise + except Exception as e: + raise InternalException(f"Failed to drop namespace: {e}") + + def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: + """List tables in a namespace.""" + ns_id = self._parse_identifier(request.id) + + if not ns_id: + raise InvalidInputException("Namespace must have at least one level") + + try: + namespace_path = ".".join(ns_id) + response = self.rest_client.get( + f"/namespaces/{namespace_path}/generic-tables" + ) + + tables = [] + if response and "identifiers" in response: + for table_id in response["identifiers"]: + table_name = table_id.get("name") + if table_name: + tables.append(table_name) + + tables = sorted(set(tables)) + + return ListTablesResponse(tables=tables) + + except RestClientException as e: + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(ns_id)}" + ) + raise InternalException(f"Failed to list tables: {e}") + except (NamespaceNotFoundException, InvalidInputException): + raise + except Exception as e: + raise InternalException(f"Failed to list tables: {e}") + + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: + """Create an empty table (metadata only operation).""" + table_id = self._parse_identifier(request.id) + + if len(table_id) < 2: + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) + + namespace = table_id[:-1] + table_name = table_id[-1] + + try: + table_path = request.location + if not table_path: + table_path = f"{self.config.root}/{'/'.join(namespace)}/{table_name}" + + properties = {self.TABLE_TYPE_KEY: self.TABLE_FORMAT_LANCE} + + create_request = { + "name": table_name, + "format": self.TABLE_FORMAT_LANCE, + "base-location": table_path, + "properties": properties, + } + + namespace_path = ".".join(namespace) + response = self.rest_client.post( + f"/namespaces/{namespace_path}/generic-tables", create_request + ) + + logger.info(f"Created table: {'.'.join(table_id)}") + + return CreateEmptyTableResponse(location=table_path) + + except RestClientException as e: + if e.is_conflict(): + raise TableAlreadyExistsException( + f"Table already exists: {'.'.join(request.id)}" + ) + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(namespace)}" + ) + raise InternalException(f"Failed to create empty table: {e}") + except ( + TableAlreadyExistsException, + NamespaceNotFoundException, + InvalidInputException, + ): + raise + except Exception as e: + raise InternalException(f"Failed to create empty table: {e}") + + def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: + """Describe a table. + + Only load_detailed_metadata=false is supported. Returns location and storage_options only. + """ + table_id = self._parse_identifier(request.id) + + if len(table_id) < 2: + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) + + namespace = table_id[:-1] + table_name = table_id[-1] + + try: + namespace_path = ".".join(namespace) + + response = self.rest_client.get( + f"/namespaces/{namespace_path}/generic-tables/{table_name}" + ) + + if not response or "table" not in response: + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" + ) + + table = response["table"] + table_format = table.get("format", "") + + if table_format.lower() != self.TABLE_FORMAT_LANCE: + raise InvalidInputException( + f"Table {'.'.join(request.id)} is not a Lance table (format: {table_format})" + ) + + return DescribeTableResponse( + location=table.get("base-location"), + storage_options=table.get("properties", {}) + ) + + except RestClientException as e: + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to describe table: {e}") + except (TableNotFoundException, InvalidInputException): + raise + except Exception as e: + raise InternalException(f"Failed to describe table: {e}") + + def table_exists(self, request: TableExistsRequest) -> None: + """Check if a table exists.""" + describe_request = DescribeTableRequest() + describe_request.id = request.id + self.describe_table(describe_request) + + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: + """Deregister a table (remove from catalog without deleting data).""" + table_id = self._parse_identifier(request.id) + + if len(table_id) < 2: + raise InvalidInputException( + "Table identifier must have at least namespace and table name" + ) + + namespace = table_id[:-1] + table_name = table_id[-1] + + try: + namespace_path = ".".join(namespace) + + response = self.rest_client.get( + f"/namespaces/{namespace_path}/generic-tables/{table_name}" + ) + + table_location = None + if response and "table" in response: + table_location = response["table"].get("base-location") + + self.rest_client.delete( + f"/namespaces/{namespace_path}/generic-tables/{table_name}" + ) + + logger.info(f"Deregistered table: {'.'.join(table_id)}") + + return DeregisterTableResponse(location=table_location) + + except RestClientException as e: + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to deregister table: {e}") + except (TableNotFoundException, InvalidInputException): + raise + except Exception as e: + raise InternalException(f"Failed to deregister table: {e}") + + def close(self): + """Close the namespace connection.""" + if self.rest_client: + self.rest_client.close() + + def _parse_identifier(self, identifier: List[str]) -> List[str]: + """Parse identifier list.""" + return identifier if identifier else [] diff --git a/python/src/lance_namespace_impls/rest_client.py b/python/src/lance_namespace_impls/rest_client.py new file mode 100644 index 0000000..604bd1f --- /dev/null +++ b/python/src/lance_namespace_impls/rest_client.py @@ -0,0 +1,282 @@ +""" +Shared REST client infrastructure for Lance namespace implementations. +""" + +import json +import logging +from typing import Any, Callable, Dict, Optional, Type, TypeVar + +import urllib3 +import urllib.parse + +logger = logging.getLogger(__name__) + +T = TypeVar("T") + + +class RestClientException(Exception): + """Exception raised by REST client.""" + + def __init__(self, status_code: int, response_body: str): + self.status_code = status_code + self.response_body = response_body + super().__init__(f"HTTP {status_code}: {response_body}") + + def is_not_found(self) -> bool: + """Check if this is a 404 Not Found error.""" + return self.status_code == 404 + + def is_conflict(self) -> bool: + """Check if this is a 409 Conflict error.""" + return self.status_code == 409 + + def is_bad_request(self) -> bool: + """Check if this is a 400 Bad Request error.""" + return self.status_code == 400 + + +class RestClient: + """ + A reusable REST client for making HTTP requests to REST APIs. + + This client provides: + - Connection pooling for efficient HTTP connections + - Configurable timeouts for connect and read operations + - Retry logic with exponential backoff + - JSON serialization/deserialization + - Support for common HTTP methods (GET, POST, DELETE) + + Example usage: + client = RestClient( + base_url="http://localhost:8080/api", + headers={"Authorization": "Bearer token"}, + connect_timeout=10000, + read_timeout=30000, + max_retries=3 + ) + response = client.get("/resource") + """ + + def __init__( + self, + base_url: str, + headers: Optional[Dict[str, str]] = None, + connect_timeout: int = 10000, + read_timeout: int = 30000, + max_retries: int = 3, + ): + """ + Initialize the REST client. + + Args: + base_url: The base URL for all requests (e.g., "http://localhost:8080/api") + headers: Default headers to include with every request + connect_timeout: Connection timeout in milliseconds (default: 10000) + read_timeout: Read timeout in milliseconds (default: 30000) + max_retries: Maximum number of retry attempts (default: 3) + """ + self.base_url = base_url.rstrip("/") + self.headers = headers.copy() if headers else {} + self.headers.setdefault("Content-Type", "application/json") + self.headers.setdefault("Accept", "application/json") + + timeout = urllib3.Timeout( + connect=connect_timeout / 1000, read=read_timeout / 1000 + ) + self.http = urllib3.PoolManager( + timeout=timeout, + retries=urllib3.Retry(total=max_retries, backoff_factor=0.3), + ) + + def _make_request( + self, + method: str, + path: str, + params: Optional[Dict[str, str]] = None, + body: Optional[Any] = None, + ) -> Any: + """Make HTTP request.""" + url = f"{self.base_url}{path}" + + if params: + query_string = urllib.parse.urlencode(params) + url = f"{url}?{query_string}" + + body_data = None + if body is not None: + if hasattr(body, "__dict__"): + body_dict = self._dataclass_to_dict(body) + elif isinstance(body, dict): + body_dict = body + else: + body_dict = body + body_data = json.dumps(body_dict).encode("utf-8") + + try: + response = self.http.request( + method, url, headers=self.headers, body=body_data + ) + + if response.status >= 400: + raise RestClientException(response.status, response.data.decode("utf-8")) + + if response.data: + return json.loads(response.data.decode("utf-8")) + return None + + except urllib3.exceptions.HTTPError as e: + raise RestClientException(500, str(e)) + + def _dataclass_to_dict(self, obj: Any) -> Dict[str, Any]: + """Convert dataclass to dictionary, handling nested structures.""" + if hasattr(obj, "__dict__"): + result = {} + for key, value in obj.__dict__.items(): + if value is not None: + if isinstance(value, list): + result[key] = [self._dataclass_to_dict(item) for item in value] + elif hasattr(value, "__dict__"): + result[key] = self._dataclass_to_dict(value) + else: + result[key] = value + return result + return obj + + def get( + self, + path: str, + params: Optional[Dict[str, str]] = None, + response_class: Optional[Type[T]] = None, + response_converter: Optional[Callable[[Dict[str, Any]], T]] = None, + ) -> Any: + """ + Make GET request. + + Args: + path: The URL path (will be appended to base_url) + params: Optional query parameters + response_class: Optional class to instantiate with response data + response_converter: Optional function to convert response dict to object + + Returns: + The response data (as dict, or converted to response_class/using response_converter) + """ + response = self._make_request("GET", path, params=params) + if response_converter and response: + return response_converter(response) + if response_class and response: + return response_class(**response) + return response + + def post( + self, + path: str, + body: Any, + response_class: Optional[Type[T]] = None, + response_converter: Optional[Callable[[Dict[str, Any]], T]] = None, + ) -> Any: + """ + Make POST request. + + Args: + path: The URL path (will be appended to base_url) + body: The request body (will be JSON serialized) + response_class: Optional class to instantiate with response data + response_converter: Optional function to convert response dict to object + + Returns: + The response data (as dict, or converted to response_class/using response_converter) + """ + response = self._make_request("POST", path, body=body) + if response_converter and response: + return response_converter(response) + if response_class and response: + return response_class(**response) + return response + + def put( + self, + path: str, + body: Any, + response_class: Optional[Type[T]] = None, + response_converter: Optional[Callable[[Dict[str, Any]], T]] = None, + ) -> Any: + """ + Make PUT request. + + Args: + path: The URL path (will be appended to base_url) + body: The request body (will be JSON serialized) + response_class: Optional class to instantiate with response data + response_converter: Optional function to convert response dict to object + + Returns: + The response data (as dict, or converted to response_class/using response_converter) + """ + response = self._make_request("PUT", path, body=body) + if response_converter and response: + return response_converter(response) + if response_class and response: + return response_class(**response) + return response + + def delete( + self, + path: str, + params: Optional[Dict[str, str]] = None, + ) -> None: + """ + Make DELETE request. + + Args: + path: The URL path (will be appended to base_url) + params: Optional query parameters + """ + self._make_request("DELETE", path, params=params) + + def close(self) -> None: + """Close the HTTP connection pool.""" + self.http.clear() + + +class NamespaceException(Exception): + """Base exception for namespace operations.""" + + def __init__(self, message: str): + super().__init__(message) + + +class NamespaceNotFoundException(NamespaceException): + """Exception raised when a namespace is not found.""" + + pass + + +class NamespaceAlreadyExistsException(NamespaceException): + """Exception raised when a namespace already exists.""" + + pass + + +class TableNotFoundException(NamespaceException): + """Exception raised when a table is not found.""" + + pass + + +class TableAlreadyExistsException(NamespaceException): + """Exception raised when a table already exists.""" + + pass + + +class InvalidInputException(NamespaceException): + """Exception raised for invalid input.""" + + pass + + +class InternalException(NamespaceException): + """Exception raised for internal errors.""" + + pass diff --git a/python/src/lance_namespace_impls/unity.py b/python/src/lance_namespace_impls/unity.py index c089461..2cf0629 100644 --- a/python/src/lance_namespace_impls/unity.py +++ b/python/src/lance_namespace_impls/unity.py @@ -2,45 +2,53 @@ Unity Catalog namespace implementation for Lance. """ -import json +import io import logging import os -from typing import Dict, List, Optional, Any +import shutil from dataclasses import dataclass, field -import urllib3 -import urllib.parse -from urllib.error import HTTPError -import io +from typing import Any, Dict, List, Optional +import lance import pyarrow as pa import pyarrow.ipc as ipc -import lance +from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( - ListNamespacesRequest, - ListNamespacesResponse, - DescribeNamespaceRequest, - DescribeNamespaceResponse, + CreateEmptyTableRequest, + CreateEmptyTableResponse, CreateNamespaceRequest, CreateNamespaceResponse, + CreateTableRequest, + CreateTableResponse, + DeregisterTableRequest, + DeregisterTableResponse, + DescribeNamespaceRequest, + DescribeNamespaceResponse, + DescribeTableRequest, + DescribeTableResponse, DropNamespaceRequest, DropNamespaceResponse, - NamespaceExistsRequest, + DropTableRequest, + DropTableResponse, + ListNamespacesRequest, + ListNamespacesResponse, ListTablesRequest, ListTablesResponse, - DescribeTableRequest, - DescribeTableResponse, + NamespaceExistsRequest, TableExistsRequest, - DropTableRequest, - DropTableResponse, - CreateTableRequest, - CreateTableResponse, - CreateEmptyTableRequest, - CreateEmptyTableResponse, ) -from lance.namespace import LanceNamespace - +from lance_namespace_impls.rest_client import ( + RestClient, + RestClientException, + InternalException, + InvalidInputException, + NamespaceAlreadyExistsException, + NamespaceNotFoundException, + TableAlreadyExistsException, + TableNotFoundException, +) logger = logging.getLogger(__name__) @@ -48,7 +56,7 @@ @dataclass class UnityNamespaceConfig: """Configuration for Unity Catalog namespace.""" - + ENDPOINT = "unity.endpoint" CATALOG = "unity.catalog" ROOT = "unity.root" @@ -56,7 +64,7 @@ class UnityNamespaceConfig: CONNECT_TIMEOUT = "unity.connect_timeout_millis" READ_TIMEOUT = "unity.read_timeout_millis" MAX_RETRIES = "unity.max_retries" - + endpoint: str catalog: str root: str @@ -64,23 +72,23 @@ class UnityNamespaceConfig: connect_timeout: int = 10000 read_timeout: int = 300000 max_retries: int = 3 - + def __init__(self, properties: Dict[str, str]): self.endpoint = properties.get(self.ENDPOINT) if not self.endpoint: raise ValueError(f"Required property {self.ENDPOINT} is not set") - + self.catalog = properties.get(self.CATALOG, "unity") self.root = properties.get(self.ROOT, "/tmp/lance") self.auth_token = properties.get(self.AUTH_TOKEN) self.connect_timeout = int(properties.get(self.CONNECT_TIMEOUT, "10000")) self.read_timeout = int(properties.get(self.READ_TIMEOUT, "300000")) self.max_retries = int(properties.get(self.MAX_RETRIES, "3")) - + def get_full_api_url(self) -> str: """Get the full API URL with /api/2.1 path.""" - base = self.endpoint.rstrip('/') - if not base.endswith('/api/2.1'): + base = self.endpoint.rstrip("/") + if not base.endswith("/api/2.1"): base = f"{base}/api/2.1" return base @@ -88,6 +96,7 @@ def get_full_api_url(self) -> str: @dataclass class SchemaInfo: """Unity schema information.""" + name: str catalog_name: str comment: Optional[str] = None @@ -101,6 +110,7 @@ class SchemaInfo: @dataclass class ColumnInfo: """Unity column information.""" + name: str type_text: str type_json: str @@ -117,6 +127,7 @@ class ColumnInfo: @dataclass class TableInfo: """Unity table information.""" + name: str catalog_name: str schema_name: str @@ -135,6 +146,7 @@ class TableInfo: @dataclass class CreateSchema: """Request to create a schema.""" + name: str catalog_name: str properties: Optional[Dict[str, str]] = None @@ -143,6 +155,7 @@ class CreateSchema: @dataclass class CreateTable: """Request to create a table.""" + name: str catalog_name: str schema_name: str @@ -153,177 +166,64 @@ class CreateTable: properties: Optional[Dict[str, str]] = None -class RestClient: - """Simple REST client for Unity Catalog API.""" - - def __init__(self, base_url: str, headers: Optional[Dict[str, str]] = None, - connect_timeout: int = 10, read_timeout: int = 300, max_retries: int = 3): - self.base_url = base_url.rstrip('/') - self.headers = headers or {} - self.headers['Content-Type'] = 'application/json' - self.headers['Accept'] = 'application/json' - - # Create urllib3 pool manager - timeout = urllib3.Timeout(connect=connect_timeout/1000, read=read_timeout/1000) - self.http = urllib3.PoolManager( - timeout=timeout, - retries=urllib3.Retry(total=max_retries, backoff_factor=0.3) - ) - - def _make_request(self, method: str, path: str, params: Optional[Dict[str, str]] = None, - body: Optional[Any] = None) -> Any: - """Make HTTP request to Unity API.""" - url = f"{self.base_url}{path}" - - # Add query parameters - if params: - query_string = urllib.parse.urlencode(params) - url = f"{url}?{query_string}" - - # Prepare body - body_data = None - if body is not None: - if hasattr(body, '__dict__'): - # Convert dataclass to dict - body_dict = self._dataclass_to_dict(body) - else: - body_dict = body - body_data = json.dumps(body_dict).encode('utf-8') - - try: - response = self.http.request( - method, - url, - headers=self.headers, - body=body_data - ) - - if response.status >= 400: - raise RestClientException(response.status, response.data.decode('utf-8')) - - if response.data: - return json.loads(response.data.decode('utf-8')) - return None - - except urllib3.exceptions.HTTPError as e: - raise RestClientException(500, str(e)) - - def _dataclass_to_dict(self, obj: Any) -> Dict[str, Any]: - """Convert dataclass to dictionary, handling nested structures.""" - if hasattr(obj, '__dict__'): - result = {} - for key, value in obj.__dict__.items(): - if value is not None: - if isinstance(value, list): - result[key] = [self._dataclass_to_dict(item) for item in value] - elif hasattr(value, '__dict__'): - result[key] = self._dataclass_to_dict(value) - else: - result[key] = value - return result - return obj - - def get(self, path: str, params: Optional[Dict[str, str]] = None, - response_class: Optional[type] = None) -> Any: - """Make GET request.""" - response = self._make_request('GET', path, params=params) - if response_class and response: - return self._dict_to_dataclass(response, response_class) - return response - - def post(self, path: str, body: Any, response_class: Optional[type] = None) -> Any: - """Make POST request.""" - response = self._make_request('POST', path, body=body) - if response_class and response: - return self._dict_to_dataclass(response, response_class) - return response - - def delete(self, path: str, params: Optional[Dict[str, str]] = None) -> None: - """Make DELETE request.""" - self._make_request('DELETE', path, params=params) - - def _dict_to_dataclass(self, data: Dict[str, Any], cls: type) -> Any: - """Convert dictionary to dataclass instance.""" - if cls == SchemaInfo: - return SchemaInfo(**data) - elif cls == TableInfo: - # Handle nested ColumnInfo objects - columns_data = data.get('columns', []) - columns = [ColumnInfo(**col) for col in columns_data] - data['columns'] = columns - return TableInfo(**data) - return data - - def close(self): - """Close the HTTP connection pool.""" - self.http.clear() - - -class RestClientException(Exception): - """Exception raised by REST client.""" - - def __init__(self, status_code: int, response_body: str): - self.status_code = status_code - self.response_body = response_body - super().__init__(f"HTTP {status_code}: {response_body}") - - -class LanceNamespaceException(Exception): - """Exception for Lance namespace operations.""" - - def __init__(self, status_code: int, message: str): - self.status_code = status_code - super().__init__(message) - - @classmethod - def not_found(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a not found exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(404, full_message) - - @classmethod - def bad_request(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a bad request exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(400, full_message) - - @classmethod - def conflict(cls, message: str, error_code: str, resource: str, details: str = ""): - """Create a conflict exception.""" - full_message = f"{message} [{error_code}]: {resource}" - if details: - full_message += f" - {details}" - return cls(409, full_message) +def _parse_schema_info(data: Dict[str, Any]) -> SchemaInfo: + """Parse SchemaInfo from response dict.""" + return SchemaInfo( + name=data.get("name", ""), + catalog_name=data.get("catalog_name", ""), + comment=data.get("comment"), + properties=data.get("properties", {}), + full_name=data.get("full_name"), + created_at=data.get("created_at"), + updated_at=data.get("updated_at"), + schema_id=data.get("schema_id"), + ) + + +def _parse_table_info(data: Dict[str, Any]) -> TableInfo: + """Parse TableInfo from response dict.""" + columns_data = data.get("columns", []) + columns = [ColumnInfo(**col) for col in columns_data] + return TableInfo( + name=data.get("name", ""), + catalog_name=data.get("catalog_name", ""), + schema_name=data.get("schema_name", ""), + table_type=data.get("table_type", ""), + data_source_format=data.get("data_source_format", ""), + columns=columns, + storage_location=data.get("storage_location", ""), + comment=data.get("comment"), + properties=data.get("properties", {}), + created_at=data.get("created_at"), + updated_at=data.get("updated_at"), + table_id=data.get("table_id"), + full_name=data.get("full_name"), + ) class UnityNamespace(LanceNamespace): """Unity Catalog namespace implementation for Lance.""" - + TABLE_TYPE_LANCE = "lance" TABLE_TYPE_EXTERNAL = "EXTERNAL" MANAGED_BY_KEY = "managed_by" TABLE_TYPE_KEY = "table_type" VERSION_KEY = "version" - + def __init__(self, **properties): """Initialize Unity namespace with configuration properties.""" self.config = UnityNamespaceConfig(properties) - - # Build REST client with authentication if provided + headers = {} if self.config.auth_token: - headers['Authorization'] = f"Bearer {self.config.auth_token}" - + headers["Authorization"] = f"Bearer {self.config.auth_token}" + self.rest_client = RestClient( base_url=self.config.get_full_api_url(), headers=headers, connect_timeout=self.config.connect_timeout, read_timeout=self.config.read_timeout, - max_retries=self.config.max_retries + max_retries=self.config.max_retries, ) logger.info(f"Initialized Unity namespace with endpoint: {self.config.endpoint}") @@ -335,326 +235,241 @@ def namespace_id(self) -> str: def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: """List namespaces.""" ns_id = self._parse_identifier(request.id) - - # Unity supports 3-level namespace: catalog.schema.table + if len(ns_id) > 2: - raise ValueError(f"Expect at most 2-level namespace but get {'.'.join(ns_id)}") - + raise InvalidInputException( + f"Expect at most 2-level namespace but get {'.'.join(ns_id)}" + ) + try: namespaces = [] - + if len(ns_id) == 0: - # Return the configured catalog as the only top-level namespace namespaces = [self.config.catalog] elif len(ns_id) == 1: - # List schemas in the catalog catalog = ns_id[0] if catalog != self.config.catalog: - raise LanceNamespaceException.not_found( - "Catalog not found", - "CATALOG_NOT_FOUND", - catalog, - f"Expected: {self.config.catalog}" + raise NamespaceNotFoundException( + f"Catalog not found: {catalog}, expected: {self.config.catalog}" ) - - params = {'catalog_name': catalog} + + params = {"catalog_name": catalog} if request.limit: - params['max_results'] = str(request.limit) + params["max_results"] = str(request.limit) if request.page_token: - params['page_token'] = request.page_token - - response = self.rest_client.get('/schemas', params=params) - - if response and 'schemas' in response: - namespaces = [schema['name'] for schema in response['schemas']] - - # Sort and deduplicate + params["page_token"] = request.page_token + + response = self.rest_client.get("/schemas", params=params) + + if response and "schemas" in response: + namespaces = [schema["name"] for schema in response["schemas"]] + namespaces = sorted(set(namespaces)) - - response = ListNamespacesResponse() - response.namespaces = namespaces - return response - + + return ListNamespacesResponse(namespaces=namespaces) + + except (NamespaceNotFoundException, InvalidInputException): + raise except Exception as e: - if isinstance(e, LanceNamespaceException): - raise - raise LanceNamespaceException(500, f"Failed to list namespaces: {e}") - + raise InternalException(f"Failed to list namespaces: {e}") + def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: """Create a new namespace.""" ns_id = self._parse_identifier(request.id) - + if len(ns_id) != 2: - raise ValueError(f"Expect a 2-level namespace but get {'.'.join(ns_id)}") - + raise InvalidInputException( + f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + ) + catalog = ns_id[0] schema = ns_id[1] - + if catalog != self.config.catalog: - raise LanceNamespaceException.bad_request( - "Cannot create namespace in catalog", - "INVALID_CATALOG", - catalog, - f"Expected: {self.config.catalog}" + raise InvalidInputException( + f"Cannot create namespace in catalog {catalog}, expected: {self.config.catalog}" ) - + try: create_schema = CreateSchema( - name=schema, - catalog_name=catalog, - properties=request.properties + name=schema, catalog_name=catalog, properties=request.properties + ) + + schema_info = self.rest_client.post( + "/schemas", create_schema, response_converter=_parse_schema_info ) - - schema_info = self.rest_client.post('/schemas', create_schema, SchemaInfo) - - response = CreateNamespaceResponse() - response.properties = schema_info.properties - return response - + + logger.info(f"Created namespace: {catalog}.{schema}") + + return CreateNamespaceResponse(properties=schema_info.properties) + except RestClientException as e: - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Namespace already exists", - "NAMESPACE_EXISTS", - '.'.join(request.id), - e.response_body + if e.is_conflict(): + raise NamespaceAlreadyExistsException( + f"Namespace already exists: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to create namespace: {e}") + raise InternalException(f"Failed to create namespace: {e}") except Exception as e: - raise LanceNamespaceException(500, f"Failed to create namespace: {e}") - - def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + if isinstance(e, (NamespaceAlreadyExistsException, InvalidInputException)): + raise + raise InternalException(f"Failed to create namespace: {e}") + + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: """Describe a namespace.""" ns_id = self._parse_identifier(request.id) - + if len(ns_id) != 2: - raise ValueError(f"Expect a 2-level namespace but get {'.'.join(ns_id)}") - + raise InvalidInputException( + f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + ) + catalog = ns_id[0] schema = ns_id[1] - + if catalog != self.config.catalog: - raise LanceNamespaceException.not_found( - "Catalog not found", - "CATALOG_NOT_FOUND", - catalog, - f"Expected: {self.config.catalog}" + raise NamespaceNotFoundException( + f"Catalog not found: {catalog}, expected: {self.config.catalog}" ) - + try: full_name = f"{catalog}.{schema}" - schema_info = self.rest_client.get(f"/schemas/{full_name}", response_class=SchemaInfo) - - response = DescribeNamespaceResponse() - response.properties = schema_info.properties - return response - + schema_info = self.rest_client.get( + f"/schemas/{full_name}", response_converter=_parse_schema_info + ) + + return DescribeNamespaceResponse(properties=schema_info.properties) + except RestClientException as e: - if e.status_code == 404: - raise LanceNamespaceException.not_found( - "Namespace not found", - "NAMESPACE_NOT_FOUND", - '.'.join(request.id), - e.response_body + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to describe namespace: {e}") + raise InternalException(f"Failed to describe namespace: {e}") except Exception as e: - raise LanceNamespaceException(500, f"Failed to describe namespace: {e}") - + if isinstance(e, (NamespaceNotFoundException, InvalidInputException)): + raise + raise InternalException(f"Failed to describe namespace: {e}") + def namespace_exists(self, request: NamespaceExistsRequest) -> None: """Check if a namespace exists.""" describe_request = DescribeNamespaceRequest() describe_request.id = request.id self.describe_namespace(describe_request) - + def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace.""" ns_id = self._parse_identifier(request.id) - + if len(ns_id) != 2: - raise ValueError(f"Expect a 2-level namespace but get {'.'.join(ns_id)}") - + raise InvalidInputException( + f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + ) + catalog = ns_id[0] schema = ns_id[1] - + if catalog != self.config.catalog: - raise LanceNamespaceException.bad_request( - "Cannot drop namespace in catalog", - "INVALID_CATALOG", - catalog, - f"Expected: {self.config.catalog}" + raise InvalidInputException( + f"Cannot drop namespace in catalog {catalog}, expected: {self.config.catalog}" ) - + try: full_name = f"{catalog}.{schema}" - params = {} - if request.behavior == DropNamespaceRequest.BehaviorEnum.CASCADE: - params['force'] = 'true' - - self.rest_client.delete(f"/schemas/{full_name}", params=params) - - return DropNamespaceResponse() - + self.rest_client.delete(f"/schemas/{full_name}") + logger.info(f"Dropped namespace: {full_name}") + + return DropNamespaceResponse(properties={}) + except RestClientException as e: - if e.status_code == 404: - # Namespace doesn't exist, return success - return DropNamespaceResponse() - raise LanceNamespaceException(500, f"Failed to drop namespace: {e}") + if e.is_not_found(): + return DropNamespaceResponse(properties={}) + raise InternalException(f"Failed to drop namespace: {e}") except Exception as e: - raise LanceNamespaceException(500, f"Failed to drop namespace: {e}") - + if isinstance(e, InvalidInputException): + raise + raise InternalException(f"Failed to drop namespace: {e}") + def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a namespace.""" ns_id = self._parse_identifier(request.id) - + if len(ns_id) != 2: - raise ValueError(f"Expect a 2-level namespace but get {'.'.join(ns_id)}") - + raise InvalidInputException( + f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + ) + catalog = ns_id[0] schema = ns_id[1] - + if catalog != self.config.catalog: - raise LanceNamespaceException.not_found( - "Catalog not found", - "CATALOG_NOT_FOUND", - catalog, - f"Expected: {self.config.catalog}" + raise NamespaceNotFoundException( + f"Catalog not found: {catalog}, expected: {self.config.catalog}" ) - + try: - params = { - 'catalog_name': catalog, - 'schema_name': schema - } + params = {"catalog_name": catalog, "schema_name": schema} if request.limit: - params['max_results'] = str(request.limit) + params["max_results"] = str(request.limit) if request.page_token: - params['page_token'] = request.page_token - - response = self.rest_client.get('/tables', params=params) - + params["page_token"] = request.page_token + + response = self.rest_client.get("/tables", params=params) + tables = [] - if response and 'tables' in response: - # Filter only Lance tables - for table_data in response['tables']: + if response and "tables" in response: + for table_data in response["tables"]: if self._is_lance_table(table_data): - tables.append(table_data['name']) - - # Sort and deduplicate + tables.append(table_data["name"]) + tables = sorted(set(tables)) - response = ListTablesResponse() - response.tables = tables - return response - - except Exception as e: - raise LanceNamespaceException(500, f"Failed to list tables: {e}") - - def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: - """Create a new table with data from Arrow IPC stream.""" - if not request_data: - raise ValueError("Request data (Arrow IPC stream) is required for createTable") - - table_id = self._parse_identifier(request.id) - - if len(table_id) != 3: - raise ValueError(f"Expect a 3-level table identifier but get {'.'.join(table_id)}") - - catalog = table_id[0] - schema = table_id[1] - table = table_id[2] - - if catalog != self.config.catalog: - raise LanceNamespaceException.bad_request( - "Cannot create table in catalog", - "INVALID_CATALOG", - catalog, - f"Expected: {self.config.catalog}" - ) - - try: - # First create an empty Lance table dataset - table_path = f"{self.config.root}/{catalog}/{schema}/{table}" - - # Extract schema from Arrow IPC stream - arrow_schema = self._extract_schema_from_ipc(request_data) - - # Create Lance dataset - lance.write_dataset( - pa.table([], schema=arrow_schema), - table_path, - mode="create" - ) - - # Create Unity table metadata - columns = self._convert_arrow_schema_to_unity_columns(arrow_schema) - - properties = { - self.TABLE_TYPE_KEY: self.TABLE_TYPE_LANCE, - self.MANAGED_BY_KEY: "storage", - self.VERSION_KEY: "0" - } - if request.properties: - properties.update(request.properties) - - create_table = CreateTable( - name=table, - catalog_name=catalog, - schema_name=schema, - table_type=self.TABLE_TYPE_EXTERNAL, - data_source_format="TEXT", # Unity doesn't recognize LANCE format - columns=columns, - storage_location=table_path, - properties=properties - ) - - table_info = self.rest_client.post('/tables', create_table, TableInfo) - - response = CreateTableResponse() - response.location = table_path - response.version = 1 - response.properties = table_info.properties - return response - - except RestClientException as e: - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - '.'.join(request.id), - e.response_body - ) - raise LanceNamespaceException(500, f"Failed to create table: {e}") + return ListTablesResponse(tables=tables) + + except (NamespaceNotFoundException, InvalidInputException): + raise except Exception as e: - raise LanceNamespaceException(500, f"Failed to create table: {e}") - - def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + raise InternalException(f"Failed to list tables: {e}") + + def create_table( + self, request: CreateTableRequest, request_data: bytes + ) -> CreateTableResponse: + """Create a new table with data from Arrow IPC stream. + + This operation is not supported. Use create_empty_table to declare table metadata, + then use Lance SDK to create the actual table data. + """ + raise NotImplementedError( + "create_table is not supported. Use create_empty_table to declare table metadata, " + "then use Lance SDK to create the actual table data." + ) + + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: """Create an empty table (metadata only operation).""" table_id = self._parse_identifier(request.id) - + if len(table_id) != 3: - raise ValueError(f"Expect a 3-level table identifier but get {'.'.join(table_id)}") - + raise InvalidInputException( + f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + ) + catalog = table_id[0] schema = table_id[1] table = table_id[2] - + if catalog != self.config.catalog: - raise LanceNamespaceException.bad_request( - "Cannot create empty table in catalog", - "INVALID_CATALOG", - catalog, - f"Expected: {self.config.catalog}" + raise InvalidInputException( + f"Cannot create empty table in catalog {catalog}, expected: {self.config.catalog}" ) - + try: - # Determine table location table_path = request.location if not table_path: table_path = f"{self.config.root}/{catalog}/{schema}/{table}" - - # Create Unity table metadata without creating Lance dataset - # For empty table, create minimal schema with just an ID column + columns = [ ColumnInfo( name="__placeholder_id", @@ -662,17 +477,15 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab type_json='{"type":"long"}', type_name="BIGINT", position=0, - nullable=True + nullable=True, ) ] - + properties = { self.TABLE_TYPE_KEY: self.TABLE_TYPE_LANCE, - self.MANAGED_BY_KEY: "catalog" + self.MANAGED_BY_KEY: "catalog", } - if request.properties: - properties.update(request.properties) - + create_table = CreateTable( name=table, catalog_name=catalog, @@ -681,206 +494,200 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab data_source_format="TEXT", columns=columns, storage_location=table_path, - properties=properties + properties=properties, + ) + + table_info = self.rest_client.post( + "/tables", create_table, response_converter=_parse_table_info ) - - table_info = self.rest_client.post('/tables', create_table, TableInfo) - - response = CreateEmptyTableResponse() - response.location = table_path - response.properties = table_info.properties - return response - + + logger.info(f"Created empty table: {catalog}.{schema}.{table}") + + return CreateEmptyTableResponse(location=table_path) + except RestClientException as e: - if e.status_code == 409: - raise LanceNamespaceException.conflict( - "Table already exists", - "TABLE_EXISTS", - '.'.join(request.id), - e.response_body + if e.is_conflict(): + raise TableAlreadyExistsException( + f"Table already exists: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to create empty table: {e}") + raise InternalException(f"Failed to create empty table: {e}") except Exception as e: - raise LanceNamespaceException(500, f"Failed to create empty table: {e}") - + if isinstance(e, (TableAlreadyExistsException, InvalidInputException)): + raise + raise InternalException(f"Failed to create empty table: {e}") + def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table.""" table_id = self._parse_identifier(request.id) - + if len(table_id) != 3: - raise ValueError(f"Expect a 3-level table identifier but get {'.'.join(table_id)}") - + raise InvalidInputException( + f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + ) + catalog = table_id[0] schema = table_id[1] table = table_id[2] - + if catalog != self.config.catalog: - raise LanceNamespaceException.not_found( - "Catalog not found", - "CATALOG_NOT_FOUND", - catalog, - f"Expected: {self.config.catalog}" + raise NamespaceNotFoundException( + f"Catalog not found: {catalog}, expected: {self.config.catalog}" ) - + try: full_name = f"{catalog}.{schema}.{table}" - table_info = self.rest_client.get(f"/tables/{full_name}", response_class=TableInfo) - + table_info = self.rest_client.get( + f"/tables/{full_name}", response_converter=_parse_table_info + ) + if not self._is_lance_table_info(table_info): - raise LanceNamespaceException.bad_request( - "Not a Lance table", - "INVALID_TABLE", - '.'.join(request.id), - "Table is not managed by Lance" + raise InvalidInputException( + f"Table {'.'.join(request.id)} is not a Lance table" ) - - # Get the actual schema from the Lance dataset - dataset = lance.dataset(table_info.storage_location) - arrow_schema = dataset.schema - - response = DescribeTableResponse() - response.location = table_info.storage_location - response.properties = table_info.properties - # TODO: Convert Arrow schema to JsonArrowSchema if needed - - return response - + + return DescribeTableResponse( + location=table_info.storage_location, + storage_options=table_info.properties + ) + except RestClientException as e: - if e.status_code == 404: - raise LanceNamespaceException.not_found( - "Table not found", - "TABLE_NOT_FOUND", - '.'.join(request.id), - e.response_body + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" ) - raise LanceNamespaceException(500, f"Failed to describe table: {e}") + raise InternalException(f"Failed to describe table: {e}") except Exception as e: - raise LanceNamespaceException(500, f"Failed to describe table: {e}") - + if isinstance( + e, + ( + TableNotFoundException, + NamespaceNotFoundException, + InvalidInputException, + ), + ): + raise + raise InternalException(f"Failed to describe table: {e}") + def table_exists(self, request: TableExistsRequest) -> None: """Check if a table exists.""" describe_request = DescribeTableRequest() describe_request.id = request.id self.describe_table(describe_request) - + def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table.""" + """Drop a table. + + This operation is not supported. Use deregister_table to remove table metadata, + then use Lance SDK to delete the actual table data if needed. + """ + raise NotImplementedError( + "drop_table is not supported. Use deregister_table to remove table metadata, " + "then use Lance SDK to delete the actual table data if needed." + ) + + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: + """Deregister a table (remove from catalog without deleting data).""" table_id = self._parse_identifier(request.id) - + if len(table_id) != 3: - raise ValueError(f"Expect a 3-level table identifier but get {'.'.join(table_id)}") - + raise InvalidInputException( + f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + ) + catalog = table_id[0] schema = table_id[1] table = table_id[2] - + if catalog != self.config.catalog: - raise LanceNamespaceException.bad_request( - "Cannot drop table in catalog", - "INVALID_CATALOG", - catalog, - f"Expected: {self.config.catalog}" + raise InvalidInputException( + f"Cannot deregister table in catalog {catalog}, expected: {self.config.catalog}" ) - + try: full_name = f"{catalog}.{schema}.{table}" - - # First get the table info to check if it's a Lance table - try: - table_info = self.rest_client.get(f"/tables/{full_name}", response_class=TableInfo) - except RestClientException as e: - if e.status_code == 404: - response = DropTableResponse() - response.id = request.id - return response - raise - + + table_info = self.rest_client.get( + f"/tables/{full_name}", response_converter=_parse_table_info + ) + if not self._is_lance_table_info(table_info): - raise LanceNamespaceException.bad_request( - "Not a Lance table", - "INVALID_TABLE", - '.'.join(request.id), - "Table is not managed by Lance" + raise InvalidInputException( + f"Table {'.'.join(request.id)} is not a Lance table" ) - - # Delete from Unity + + location = table_info.storage_location self.rest_client.delete(f"/tables/{full_name}") - - # Delete Lance dataset data - try: - import shutil - if os.path.exists(table_info.storage_location): - shutil.rmtree(table_info.storage_location) - except Exception as e: - # Log warning but continue - Unity metadata already deleted - logger.warning(f"Failed to delete Lance dataset at {table_info.storage_location}: {e}") - - response = DropTableResponse() - response.id = request.id - response.location = table_info.storage_location - return response - + + logger.info(f"Deregistered table: {full_name}") + + return DeregisterTableResponse(location=location) + + except RestClientException as e: + if e.is_not_found(): + raise TableNotFoundException( + f"Table not found: {'.'.join(request.id)}" + ) + raise InternalException(f"Failed to deregister table: {e}") except Exception as e: - if isinstance(e, LanceNamespaceException): + if isinstance(e, (TableNotFoundException, InvalidInputException)): raise - raise LanceNamespaceException(500, f"Failed to drop table: {e}") - + raise InternalException(f"Failed to deregister table: {e}") + def close(self): """Close the namespace connection.""" if self.rest_client: self.rest_client.close() - + def _parse_identifier(self, identifier: List[str]) -> List[str]: """Parse identifier list.""" return identifier if identifier else [] - + def _is_lance_table(self, table_data: Dict[str, Any]) -> bool: """Check if a table dictionary represents a Lance table.""" - if not table_data or 'properties' not in table_data: + if not table_data or "properties" not in table_data: return False - properties = table_data.get('properties', {}) + properties = table_data.get("properties", {}) table_type = properties.get(self.TABLE_TYPE_KEY) return table_type and table_type.lower() == self.TABLE_TYPE_LANCE.lower() - + def _is_lance_table_info(self, table_info: TableInfo) -> bool: """Check if a TableInfo represents a Lance table.""" if not table_info or not table_info.properties: return False table_type = table_info.properties.get(self.TABLE_TYPE_KEY) return table_type and table_type.lower() == self.TABLE_TYPE_LANCE.lower() - + def _extract_schema_from_ipc(self, ipc_data: bytes) -> pa.Schema: """Extract Arrow schema from IPC stream.""" try: reader = ipc.open_stream(io.BytesIO(ipc_data)) return reader.schema except Exception as e: - raise LanceNamespaceException.bad_request( - f"Invalid Arrow IPC stream: {e}", - "INVALID_ARROW_IPC", - "", - "Failed to extract schema from Arrow IPC stream" - ) - - def _convert_arrow_schema_to_unity_columns(self, arrow_schema: pa.Schema) -> List[ColumnInfo]: + raise InvalidInputException(f"Invalid Arrow IPC stream: {e}") + + def _convert_arrow_schema_to_unity_columns( + self, arrow_schema: pa.Schema + ) -> List[ColumnInfo]: """Convert Arrow schema to Unity column definitions.""" columns = [] for i, field in enumerate(arrow_schema): unity_type = self._convert_arrow_type_to_unity_type(field.type) unity_type_json = self._convert_arrow_type_to_unity_type_json(field.type) - + column = ColumnInfo( name=field.name, type_text=unity_type, type_json=unity_type_json, type_name=unity_type, position=i, - nullable=field.nullable + nullable=field.nullable, ) columns.append(column) - + return columns - + def _convert_arrow_type_to_unity_type(self, arrow_type: pa.DataType) -> str: """Convert Arrow type to Unity type string.""" if pa.types.is_string(arrow_type) or pa.types.is_large_string(arrow_type): @@ -900,9 +707,8 @@ def _convert_arrow_type_to_unity_type(self, arrow_type: pa.DataType) -> str: elif pa.types.is_timestamp(arrow_type): return "TIMESTAMP" else: - # Default fallback return "STRING" - + def _convert_arrow_type_to_unity_type_json(self, arrow_type: pa.DataType) -> str: """Convert Arrow type to Unity type JSON string.""" if pa.types.is_string(arrow_type) or pa.types.is_large_string(arrow_type): @@ -922,5 +728,4 @@ def _convert_arrow_type_to_unity_type_json(self, arrow_type: pa.DataType) -> str elif pa.types.is_timestamp(arrow_type): return '{"type":"timestamp"}' else: - # Default fallback - return '{"type":"string"}' \ No newline at end of file + return '{"type":"string"}' diff --git a/python/tests/test_glue.py b/python/tests/test_glue.py index cc5b70c..596001d 100644 --- a/python/tests/test_glue.py +++ b/python/tests/test_glue.py @@ -5,7 +5,7 @@ from unittest.mock import Mock, MagicMock, patch import pyarrow as pa -from lance_namespace.glue import GlueNamespace, GlueNamespaceConfig +from lance_namespace_impls.glue import GlueNamespace, GlueNamespaceConfig from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, CreateNamespaceRequest, @@ -19,16 +19,13 @@ RegisterTableRequest, DeregisterTableRequest, TableExistsRequest, - JsonArrowSchema, - JsonArrowField, - JsonArrowDataType, ) @pytest.fixture def mock_boto3(): """Mock boto3 module.""" - with patch('lance_namespace.glue.boto3') as mock: + with patch('lance_namespace_impls.glue.boto3') as mock: mock.Session.return_value.client.return_value = MagicMock() yield mock @@ -36,7 +33,7 @@ def mock_boto3(): @pytest.fixture def mock_lance(): """Mock lance module.""" - with patch('lance_namespace.glue.lance') as mock: + with patch('lance_namespace_impls.glue.lance') as mock: yield mock @@ -102,7 +99,7 @@ class TestGlueNamespace: def test_initialization_without_boto3(self): """Test that initialization fails without boto3.""" - with patch('lance_namespace.glue.HAS_BOTO3', False): + with patch('lance_namespace_impls.glue.HAS_BOTO3', False): with pytest.raises(ImportError, match="boto3 is required"): GlueNamespace() @@ -312,124 +309,19 @@ def test_list_tables(self, glue_namespace): assert response.tables == ['table1', 'table2'] glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName='test_db') - def test_create_table(self, glue_namespace, mock_lance): - """Test creating a table.""" - glue_namespace.glue.get_database.return_value = { - 'Database': {'LocationUri': 's3://bucket/db'} - } - - schema = JsonArrowSchema( - fields=[ - JsonArrowField(name='id', type=JsonArrowDataType(type='int64'), nullable=False), - JsonArrowField(name='name', type=JsonArrowDataType(type='utf8'), nullable=True), - ] - ) - - request = CreateTableRequest( - id=['test_db', 'test_table'], - var_schema=schema - ) - - # Create mock Arrow IPC stream data - arrow_schema = pa.schema([ - pa.field('id', pa.int64(), nullable=False), - pa.field('name', pa.string(), nullable=True), - ]) - table = pa.table({'id': [1, 2], 'name': ['Alice', 'Bob']}, schema=arrow_schema) - - # Convert to IPC stream bytes - with pa.BufferOutputStream() as sink: - with pa.ipc.new_stream(sink, arrow_schema) as writer: - writer.write_table(table) - request_data = sink.getvalue().to_pybytes() - - response = glue_namespace.create_table(request, request_data) - - assert response.location == 's3://bucket/db/test_table.lance' - assert response.version == 1 - - # Verify Lance dataset was written - mock_lance.write_dataset.assert_called_once() - - # Verify Glue table was created - glue_namespace.glue.create_table.assert_called_once() - call_args = glue_namespace.glue.create_table.call_args - assert call_args[1]['DatabaseName'] == 'test_db' - assert call_args[1]['TableInput']['Name'] == 'test_table' - assert call_args[1]['TableInput']['Parameters']['table_type'] == 'LANCE' - - def test_create_table_empty_data(self, glue_namespace, mock_lance): - """Test creating a table with empty data.""" - import pyarrow as pa - import io - - glue_namespace.glue.get_database.return_value = { - 'Database': {'LocationUri': 's3://bucket/db'} - } - - # Create an empty Arrow table with schema - arrow_schema = pa.schema([ - pa.field('id', pa.int64(), nullable=False), - pa.field('name', pa.utf8(), nullable=True), - ]) - # Create empty arrays for each field - empty_arrays = [ - pa.array([], type=pa.int64()), - pa.array([], type=pa.utf8()) - ] - empty_table = pa.table(empty_arrays, schema=arrow_schema) - - # Convert to Arrow IPC stream - buffer = io.BytesIO() - with pa.ipc.RecordBatchStreamWriter(buffer, arrow_schema) as writer: - writer.write_table(empty_table) - ipc_data = buffer.getvalue() - - request = CreateTableRequest( - id=['test_db', 'test_table'] - ) - - # Test with empty IPC stream - response = glue_namespace.create_table(request, ipc_data) - - assert response.location == 's3://bucket/db/test_table.lance' - assert response.version == 1 - - # Verify Lance dataset was written with empty table - mock_lance.write_dataset.assert_called_once() - written_table = mock_lance.write_dataset.call_args[0][0] - assert written_table.num_rows == 0 - assert len(written_table.schema) == 2 # id and name columns - - def test_drop_table(self, glue_namespace, mock_lance): - """Test dropping a table.""" - # Mock the Glue get_table response - glue_namespace.glue.get_table.return_value = { - 'Table': { - 'Name': 'test_table', - 'Parameters': {'table_type': 'LANCE'}, - 'StorageDescriptor': {'Location': 's3://bucket/table.lance'} - } - } - - # Mock the Lance dataset - mock_dataset = mock_lance.dataset.return_value - + def test_create_table_not_supported(self, glue_namespace, mock_lance): + """Test that create_table raises NotImplementedError.""" + request = CreateTableRequest(id=['test_db', 'test_table']) + + with pytest.raises(NotImplementedError, match="create_table is not supported"): + glue_namespace.create_table(request, b"test_data") + + def test_drop_table_not_supported(self, glue_namespace, mock_lance): + """Test that drop_table raises NotImplementedError.""" request = DropTableRequest(id=['test_db', 'test_table']) - response = glue_namespace.drop_table(request) - - # Verify Lance dataset was deleted first - mock_lance.dataset.assert_called_once_with( - 's3://bucket/table.lance', - storage_options={} - ) - mock_dataset.delete.assert_called_once() - - # Then verify Glue table was deleted - glue_namespace.glue.delete_table.assert_called_once_with( - DatabaseName='test_db', - Name='test_table' - ) + + with pytest.raises(NotImplementedError, match="drop_table is not supported"): + glue_namespace.drop_table(request) def test_deregister_table(self, glue_namespace, mock_lance): """Test deregistering a table (only removes from Glue, keeps Lance dataset).""" diff --git a/python/tests/test_hive.py b/python/tests/test_hive2.py similarity index 79% rename from python/tests/test_hive.py rename to python/tests/test_hive2.py index 637a628..764a8db 100644 --- a/python/tests/test_hive.py +++ b/python/tests/test_hive2.py @@ -7,7 +7,7 @@ from unittest.mock import Mock, MagicMock, patch import pyarrow as pa -from lance_namespace import connect +from lance_namespace_impls.hive2 import Hive2Namespace from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, DescribeNamespaceRequest, @@ -20,15 +20,14 @@ DeregisterTableRequest, TableExistsRequest, DropTableRequest, - CreateTableRequest, ) @pytest.fixture def mock_hive_client(): """Create a mock Hive client.""" - with patch("lance_namespace.hive.HIVE_AVAILABLE", True): - with patch("lance_namespace.hive.HiveMetastoreClient") as mock_client_class: + with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client_class: mock_client = MagicMock() mock_client_class.return_value = mock_client yield mock_client @@ -37,44 +36,44 @@ def mock_hive_client(): @pytest.fixture def hive_namespace(mock_hive_client): """Create a Hive2Namespace instance with mocked client.""" - with patch("lance_namespace.hive.HIVE_AVAILABLE", True): - namespace = connect("hive2", { - "uri": "thrift://localhost:9083", - "root": "/tmp/warehouse" - }) + with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): + namespace = Hive2Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse" + ) namespace._client = mock_hive_client return namespace class TestHive2Namespace: """Test cases for Hive2Namespace.""" - + def test_initialization(self): """Test namespace initialization.""" - with patch("lance_namespace.hive.HIVE_AVAILABLE", True): - with patch("lance_namespace.hive.HiveMetastoreClient") as mock_client: - namespace = connect("hive2", { - "uri": "thrift://localhost:9083", - "root": "/tmp/warehouse", - "ugi": "user:group1,group2" - }) - + with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client: + namespace = Hive2Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse", + ugi="user:group1,group2" + ) + assert namespace.uri == "thrift://localhost:9083" assert namespace.root == "/tmp/warehouse" assert namespace.ugi == "user:group1,group2" - + # Client should not be initialized yet (lazy loading) mock_client.assert_not_called() - + # Access the client property to trigger initialization _ = namespace.client mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") - + def test_initialization_without_hive_deps(self): """Test that initialization fails gracefully without Hive dependencies.""" - with patch("lance_namespace.hive.HIVE_AVAILABLE", False): - with pytest.raises(ValueError, match="Hive dependencies not installed"): - connect("hive2", {"uri": "thrift://localhost:9083"}) + with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", False): + with pytest.raises(ImportError, match="Hive dependencies not installed"): + Hive2Namespace(uri="thrift://localhost:9083") def test_list_namespaces(self, hive_namespace, mock_hive_client): """Test listing namespaces (databases).""" @@ -116,7 +115,7 @@ def test_create_namespace(self, hive_namespace, mock_hive_client): mock_hive_client.__enter__.return_value = mock_client_instance # Mock HiveDatabase class - with patch("lance_namespace.hive.HiveDatabase") as mock_hive_db_class: + with patch("lance_namespace_impls.hive2.HiveDatabase") as mock_hive_db_class: mock_hive_db = MagicMock() mock_hive_db_class.return_value = mock_hive_db @@ -203,31 +202,23 @@ def test_describe_table(self, hive_namespace, mock_hive_client): """Test describing a table returns Hive metadata without opening Lance dataset.""" mock_table = MagicMock() mock_table.sd.location = "/tmp/warehouse/test_db.db/test_table" - mock_table.owner = "table_owner" # Set owner on table object + mock_table.owner = "table_owner" mock_table.parameters = { "table_type": "lance", - "version": "42", # Use 'version' not 'lance.version' per hive.md spec - "created_time": "2024-01-01" + "version": "42", } - + mock_client_instance = MagicMock() mock_client_instance.get_table.return_value = mock_table mock_hive_client.__enter__.return_value = mock_client_instance - + request = DescribeTableRequest(id=["test_db", "test_table"]) response = hive_namespace.describe_table(request) - - # Verify response contains Hive metadata + assert response.location == "/tmp/warehouse/test_db.db/test_table" - assert response.version == 42 # Parsed from lance.version - assert response.var_schema is None # No schema since we don't open Lance dataset - assert response.properties["owner"] == "table_owner" # From table.owner - assert response.properties["created_time"] == "2024-01-01" - # Properties should include all parameters from Hive - assert response.properties["table_type"] == "lance" - assert response.properties["version"] == "42" - - # Verify we called get_table but didn't try to open Lance dataset + assert response.version == 42 + assert response.var_schema is None + mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") def test_register_table(self, hive_namespace, mock_hive_client): @@ -242,7 +233,7 @@ def test_register_table(self, hive_namespace, mock_hive_client): "name": ["Alice", "Bob", "Charlie"] }) - with patch("lance_namespace.hive.lance.dataset") as mock_dataset_func: + with patch("lance_namespace_impls.hive2.lance.dataset") as mock_dataset_func: mock_dataset = MagicMock() mock_dataset.schema = data.schema mock_dataset.version = 1 @@ -252,10 +243,10 @@ def test_register_table(self, hive_namespace, mock_hive_client): mock_hive_client.__enter__.return_value = mock_client_instance # Mock all Hive classes - with patch("lance_namespace.hive.HiveTable") as mock_hive_table_class, \ - patch("lance_namespace.hive.StorageDescriptor") as mock_sd_class, \ - patch("lance_namespace.hive.SerDeInfo") as mock_serde_class, \ - patch("lance_namespace.hive.FieldSchema") as mock_field_class: + with patch("lance_namespace_impls.hive2.HiveTable") as mock_hive_table_class, \ + patch("lance_namespace_impls.hive2.StorageDescriptor") as mock_sd_class, \ + patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, \ + patch("lance_namespace_impls.hive2.FieldSchema") as mock_field_class: mock_hive_table = MagicMock() mock_hive_table_class.return_value = mock_hive_table @@ -306,7 +297,7 @@ def test_register_table_impl_managed(self, hive_namespace, mock_hive_client): "name": ["Alice", "Bob", "Charlie"] }) - with patch("lance_namespace.hive.lance.dataset") as mock_dataset_func: + with patch("lance_namespace_impls.hive2.lance.dataset") as mock_dataset_func: mock_dataset = MagicMock() mock_dataset.schema = data.schema mock_dataset.version = 42 @@ -316,10 +307,10 @@ def test_register_table_impl_managed(self, hive_namespace, mock_hive_client): mock_hive_client.__enter__.return_value = mock_client_instance # Mock all Hive classes - with patch("lance_namespace.hive.HiveTable") as mock_hive_table_class, \ - patch("lance_namespace.hive.StorageDescriptor") as mock_sd_class, \ - patch("lance_namespace.hive.SerDeInfo") as mock_serde_class, \ - patch("lance_namespace.hive.FieldSchema") as mock_field_class: + with patch("lance_namespace_impls.hive2.HiveTable") as mock_hive_table_class, \ + patch("lance_namespace_impls.hive2.StorageDescriptor") as mock_sd_class, \ + patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, \ + patch("lance_namespace_impls.hive2.FieldSchema") as mock_field_class: mock_hive_table = MagicMock() mock_hive_table_class.return_value = mock_hive_table @@ -357,22 +348,12 @@ def test_table_exists(self, hive_namespace, mock_hive_client): mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - def test_drop_table(self, hive_namespace, mock_hive_client): - """Test dropping a table.""" - mock_table = MagicMock() - mock_table.parameters = {"table_type": "lance"} - - mock_client_instance = MagicMock() - mock_client_instance.get_table.return_value = mock_table - mock_hive_client.__enter__.return_value = mock_client_instance - + def test_drop_table_not_supported(self, hive_namespace, mock_hive_client): + """Test that drop_table raises NotImplementedError.""" request = DropTableRequest(id=["test_db", "test_table"]) - response = hive_namespace.drop_table(request) - - mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - mock_client_instance.drop_table.assert_called_once_with( - "test_db", "test_table", deleteData=True - ) + + with pytest.raises(NotImplementedError, match="drop_table is not supported"): + hive_namespace.drop_table(request) def test_deregister_table(self, hive_namespace, mock_hive_client): """Test deregistering a table without deleting data.""" @@ -439,41 +420,36 @@ def test_root_namespace_operations(self, hive_namespace): def test_pickle_support(self): """Test that Hive2Namespace can be pickled and unpickled for Ray compatibility.""" import pickle - - with patch("lance_namespace.hive.HIVE_AVAILABLE", True): - with patch("lance_namespace.hive.HiveMetastoreClient"): - # Create a Hive2Namespace instance - namespace = connect("hive2", { - "uri": "thrift://localhost:9083", - "root": "/tmp/warehouse", - "ugi": "user:group1,group2", - "client.pool-size": "5", - "storage.access_key_id": "test-key", - "storage.secret_access_key": "test-secret" - }) - - # Test pickling + + with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive2.HiveMetastoreClient"): + namespace = Hive2Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse", + ugi="user:group1,group2", + **{ + "client.pool-size": "5", + "storage.access_key_id": "test-key", + "storage.secret_access_key": "test-secret" + } + ) + pickled = pickle.dumps(namespace) assert pickled is not None - - # Test unpickling + restored = pickle.loads(pickled) - assert isinstance(restored, namespace.__class__) - - # Verify configuration is preserved + assert isinstance(restored, Hive2Namespace) + assert restored.uri == "thrift://localhost:9083" assert restored.root == "/tmp/warehouse" assert restored.ugi == "user:group1,group2" assert restored.pool_size == 5 assert restored.storage_properties["access_key_id"] == "test-key" assert restored.storage_properties["secret_access_key"] == "test-secret" - - # Verify client is None after unpickling (will be lazily initialized) + assert restored._client is None - - # Test that client can be re-initialized after unpickling - with patch("lance_namespace.hive.HiveMetastoreClient") as mock_client: - # This will create a new mock client when accessed + + with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client: client = restored.client assert client is not None assert restored._client is not None diff --git a/python/tests/test_hive3.py b/python/tests/test_hive3.py new file mode 100644 index 0000000..b1af11b --- /dev/null +++ b/python/tests/test_hive3.py @@ -0,0 +1,375 @@ +""" +Tests for Lance Hive3 Namespace implementation. +""" +import os +import pytest +import tempfile +from unittest.mock import Mock, MagicMock, patch +import pyarrow as pa + +from lance_namespace_impls.hive3 import Hive3Namespace +from lance_namespace_urllib3_client.models import ( + ListNamespacesRequest, + DescribeNamespaceRequest, + CreateNamespaceRequest, + DropNamespaceRequest, + NamespaceExistsRequest, + ListTablesRequest, + DescribeTableRequest, + RegisterTableRequest, + DeregisterTableRequest, + TableExistsRequest, + DropTableRequest, +) + + +@pytest.fixture +def mock_hive_client(): + """Create a mock Hive client.""" + with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client_class: + mock_client = MagicMock() + mock_client_class.return_value = mock_client + yield mock_client + + +@pytest.fixture +def hive_namespace(mock_hive_client): + """Create a Hive3Namespace instance with mocked client.""" + with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): + namespace = Hive3Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse" + ) + namespace._client = mock_hive_client + return namespace + + +class TestHive3Namespace: + """Test cases for Hive3Namespace.""" + + def test_initialization(self): + """Test namespace initialization.""" + with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client: + namespace = Hive3Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse", + ugi="user:group1,group2" + ) + + assert namespace.uri == "thrift://localhost:9083" + assert namespace.root == "/tmp/warehouse" + assert namespace.ugi == "user:group1,group2" + + mock_client.assert_not_called() + + _ = namespace.client + mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") + + def test_initialization_without_hive_deps(self): + """Test that initialization fails gracefully without Hive dependencies.""" + with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", False): + with pytest.raises(ImportError, match="Hive dependencies not installed"): + Hive3Namespace(uri="thrift://localhost:9083") + + def test_list_namespaces_root(self, hive_namespace, mock_hive_client): + """Test listing catalogs at root level.""" + mock_client_instance = MagicMock() + mock_catalogs = MagicMock() + mock_catalogs.names = ["hive", "custom_catalog"] + mock_client_instance.get_catalogs.return_value = mock_catalogs + mock_hive_client.__enter__.return_value = mock_client_instance + + request = ListNamespacesRequest() + response = hive_namespace.list_namespaces(request) + + assert "hive" in response.namespaces + assert "custom_catalog" in response.namespaces + + def test_list_namespaces_catalog_level(self, hive_namespace, mock_hive_client): + """Test listing databases in a catalog.""" + mock_client_instance = MagicMock() + mock_client_instance.get_all_databases.return_value = ["default", "test_db", "prod_db"] + mock_hive_client.__enter__.return_value = mock_client_instance + + request = ListNamespacesRequest(id=["hive"]) + response = hive_namespace.list_namespaces(request) + + assert response.namespaces == ["test_db", "prod_db"] + mock_client_instance.get_all_databases.assert_called_once() + + def test_describe_namespace_catalog(self, hive_namespace, mock_hive_client): + """Test describing a catalog namespace.""" + request = DescribeNamespaceRequest(id=["hive"]) + response = hive_namespace.describe_namespace(request) + + assert "Catalog: hive" in response.properties["description"] + assert "catalog.location.uri" in response.properties + + def test_describe_namespace_database(self, hive_namespace, mock_hive_client): + """Test describing a database namespace.""" + mock_database = MagicMock() + mock_database.description = "Test database" + mock_database.ownerName = "test_user" + mock_database.locationUri = "/tmp/warehouse/test_db" + mock_database.parameters = {"key": "value"} + + mock_client_instance = MagicMock() + mock_client_instance.get_database.return_value = mock_database + mock_hive_client.__enter__.return_value = mock_client_instance + + request = DescribeNamespaceRequest(id=["hive", "test_db"]) + response = hive_namespace.describe_namespace(request) + + assert response.properties["comment"] == "Test database" + assert response.properties["owner"] == "test_user" + assert response.properties["location"] == "/tmp/warehouse/test_db" + mock_client_instance.get_database.assert_called_once_with("test_db") + + def test_create_namespace_database(self, hive_namespace, mock_hive_client): + """Test creating a database namespace.""" + mock_client_instance = MagicMock() + mock_hive_client.__enter__.return_value = mock_client_instance + + with patch("lance_namespace_impls.hive3.HiveDatabase") as mock_hive_db_class: + mock_hive_db = MagicMock() + mock_hive_db_class.return_value = mock_hive_db + + request = CreateNamespaceRequest( + id=["hive", "test_db"], + properties={"comment": "Test database", "owner": "test_user"} + ) + response = hive_namespace.create_namespace(request) + + mock_client_instance.create_database.assert_called_once_with(mock_hive_db) + assert mock_hive_db.name == "test_db" + + def test_drop_namespace_database(self, hive_namespace, mock_hive_client): + """Test dropping a database namespace.""" + mock_client_instance = MagicMock() + mock_client_instance.get_all_tables.return_value = [] + mock_hive_client.__enter__.return_value = mock_client_instance + + request = DropNamespaceRequest(id=["hive", "test_db"]) + response = hive_namespace.drop_namespace(request) + + mock_client_instance.drop_database.assert_called_once_with("test_db", deleteData=True, cascade=False) + + def test_namespace_exists_database(self, hive_namespace, mock_hive_client): + """Test checking if a database namespace exists.""" + mock_client_instance = MagicMock() + mock_hive_client.__enter__.return_value = mock_client_instance + + request = NamespaceExistsRequest(id=["hive", "test_db"]) + hive_namespace.namespace_exists(request) + + mock_client_instance.get_database.assert_called_once_with("test_db") + + def test_list_tables(self, hive_namespace, mock_hive_client): + """Test listing tables in a database.""" + mock_table1 = MagicMock() + mock_table1.parameters = {"table_type": "lance"} + + mock_table2 = MagicMock() + mock_table2.parameters = {"other_type": "OTHER"} + + mock_table3 = MagicMock() + mock_table3.parameters = {"table_type": "lance"} + + mock_client_instance = MagicMock() + mock_client_instance.get_all_tables.return_value = ["table1", "table2", "table3"] + mock_client_instance.get_table.side_effect = [mock_table1, mock_table2, mock_table3] + mock_hive_client.__enter__.return_value = mock_client_instance + + request = ListTablesRequest(id=["hive", "test_db"]) + response = hive_namespace.list_tables(request) + + assert response.tables == ["table1", "table3"] + mock_client_instance.get_all_tables.assert_called_once_with("test_db") + + def test_describe_table(self, hive_namespace, mock_hive_client): + """Test describing a table with 3-level identifier.""" + mock_table = MagicMock() + mock_table.sd.location = "/tmp/warehouse/test_db/test_table" + mock_table.parameters = { + "table_type": "lance", + "version": "42", + } + + mock_client_instance = MagicMock() + mock_client_instance.get_table.return_value = mock_table + mock_hive_client.__enter__.return_value = mock_client_instance + + request = DescribeTableRequest(id=["hive", "test_db", "test_table"]) + response = hive_namespace.describe_table(request) + + assert response.location == "/tmp/warehouse/test_db/test_table" + assert response.version == 42 + + mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") + + def test_register_table(self, hive_namespace, mock_hive_client): + """Test registering a Lance table with 3-level identifier.""" + with tempfile.TemporaryDirectory() as tmpdir: + table_path = os.path.join(tmpdir, "test_table") + + data = pa.table({ + "id": [1, 2, 3], + "name": ["Alice", "Bob", "Charlie"] + }) + + with patch("lance_namespace_impls.hive3.lance.dataset") as mock_dataset_func: + mock_dataset = MagicMock() + mock_dataset.schema = data.schema + mock_dataset.version = 1 + mock_dataset_func.return_value = mock_dataset + + mock_client_instance = MagicMock() + mock_hive_client.__enter__.return_value = mock_client_instance + + with patch("lance_namespace_impls.hive3.HiveTable") as mock_hive_table_class, \ + patch("lance_namespace_impls.hive3.StorageDescriptor") as mock_sd_class, \ + patch("lance_namespace_impls.hive3.SerDeInfo") as mock_serde_class, \ + patch("lance_namespace_impls.hive3.FieldSchema") as mock_field_class: + + mock_hive_table = MagicMock() + mock_hive_table_class.return_value = mock_hive_table + mock_sd = MagicMock() + mock_sd_class.return_value = mock_sd + mock_serde = MagicMock() + mock_serde_class.return_value = mock_serde + mock_field_class.return_value = MagicMock() + + request = RegisterTableRequest( + id=["hive", "test_db", "test_table"], + location=table_path, + properties={"owner": "test_user"} + ) + response = hive_namespace.register_table(request) + + assert response.location == table_path + mock_client_instance.create_table.assert_called_once_with(mock_hive_table) + assert mock_hive_table.dbName == "test_db" + assert mock_hive_table.tableName == "test_table" + + def test_table_exists(self, hive_namespace, mock_hive_client): + """Test checking if a table exists with 3-level identifier.""" + mock_table = MagicMock() + mock_table.parameters = {"table_type": "lance"} + + mock_client_instance = MagicMock() + mock_client_instance.get_table.return_value = mock_table + mock_hive_client.__enter__.return_value = mock_client_instance + + request = TableExistsRequest(id=["hive", "test_db", "test_table"]) + hive_namespace.table_exists(request) + + mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") + + def test_drop_table_not_supported(self, hive_namespace, mock_hive_client): + """Test that drop_table raises NotImplementedError.""" + request = DropTableRequest(id=["hive", "test_db", "test_table"]) + + with pytest.raises(NotImplementedError, match="drop_table is not supported"): + hive_namespace.drop_table(request) + + def test_deregister_table(self, hive_namespace, mock_hive_client): + """Test deregistering a table with 3-level identifier.""" + mock_table = MagicMock() + mock_table.parameters = {"table_type": "lance"} + mock_table.sd.location = "/tmp/test_table" + + mock_client_instance = MagicMock() + mock_client_instance.get_table.return_value = mock_table + mock_hive_client.__enter__.return_value = mock_client_instance + + request = DeregisterTableRequest(id=["hive", "test_db", "test_table"]) + response = hive_namespace.deregister_table(request) + + assert response.location == "/tmp/test_table" + mock_client_instance.drop_table.assert_called_once_with( + "test_db", "test_table", deleteData=False + ) + + def test_normalize_identifier(self, hive_namespace): + """Test identifier normalization for 3-level hierarchy.""" + # Single element defaults to (hive, default, table) + assert hive_namespace._normalize_identifier(["test_table"]) == ("hive", "default", "test_table") + + # Two elements defaults to (hive, database, table) + assert hive_namespace._normalize_identifier(["test_db", "test_table"]) == ("hive", "test_db", "test_table") + + # Three elements is (catalog, database, table) + assert hive_namespace._normalize_identifier(["my_cat", "test_db", "test_table"]) == ("my_cat", "test_db", "test_table") + + # More than three elements should raise an error + with pytest.raises(ValueError, match="Invalid identifier"): + hive_namespace._normalize_identifier(["a", "b", "c", "d"]) + + def test_get_table_location(self, hive_namespace): + """Test getting table location for 3-level hierarchy.""" + location = hive_namespace._get_table_location("hive", "test_db", "test_table") + assert location == "/tmp/warehouse/test_db/test_table.lance" + + def test_root_namespace_operations(self, hive_namespace): + """Test root namespace operations.""" + # namespace_exists for root should not raise + request = NamespaceExistsRequest(id=[]) + hive_namespace.namespace_exists(request) + + # describe_namespace for root + request = DescribeNamespaceRequest(id=[]) + response = hive_namespace.describe_namespace(request) + assert response.properties["location"] == "/tmp/warehouse" + + # list_tables for root should be empty + request = ListTablesRequest(id=[]) + response = hive_namespace.list_tables(request) + assert response.tables == [] + + # create_namespace for root should fail + request = CreateNamespaceRequest(id=[]) + with pytest.raises(ValueError, match="Root namespace already exists"): + hive_namespace.create_namespace(request) + + # drop_namespace for root should fail + request = DropNamespaceRequest(id=[]) + with pytest.raises(ValueError, match="Cannot drop root namespace"): + hive_namespace.drop_namespace(request) + + def test_pickle_support(self): + """Test that Hive3Namespace can be pickled and unpickled.""" + import pickle + + with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): + with patch("lance_namespace_impls.hive3.Hive3MetastoreClient"): + namespace = Hive3Namespace( + uri="thrift://localhost:9083", + root="/tmp/warehouse", + ugi="user:group1,group2", + **{ + "client.pool-size": "5", + "storage.access_key_id": "test-key", + "storage.secret_access_key": "test-secret" + } + ) + + pickled = pickle.dumps(namespace) + assert pickled is not None + + restored = pickle.loads(pickled) + assert isinstance(restored, Hive3Namespace) + + assert restored.uri == "thrift://localhost:9083" + assert restored.root == "/tmp/warehouse" + assert restored.ugi == "user:group1,group2" + assert restored.pool_size == 5 + assert restored.storage_properties["access_key_id"] == "test-key" + + assert restored._client is None + + with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client: + client = restored.client + assert client is not None + mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") diff --git a/python/tests/test_namespace.py b/python/tests/test_namespace.py index 03583f0..4c21999 100644 --- a/python/tests/test_namespace.py +++ b/python/tests/test_namespace.py @@ -13,9 +13,9 @@ def namespace_id(self) -> str: return "MockNamespace { }" def test_connect_with_short_name_rest(): - with patch('lance_namespace.namespace.importlib.import_module') as mock_import: + with patch('lance_namespace.importlib.import_module') as mock_import: mock_module = Mock() - mock_module.LanceRestNamespace = MockNamespace + mock_module.RestNamespace = MockNamespace mock_import.return_value = mock_module ns = connect("rest", {"uri": "http://localhost:8080"}) @@ -25,7 +25,7 @@ def test_connect_with_short_name_rest(): def test_connect_with_full_class_path(): - with patch('lance_namespace.namespace.importlib.import_module') as mock_import: + with patch('lance_namespace.importlib.import_module') as mock_import: mock_module = Mock() mock_module.CustomNamespace = MockNamespace mock_import.return_value = mock_module @@ -37,7 +37,7 @@ def test_connect_with_full_class_path(): def test_connect_invalid_implementation(): - with patch('lance_namespace.namespace.importlib.import_module') as mock_import: + with patch('lance_namespace.importlib.import_module') as mock_import: mock_import.side_effect = ImportError("Module not found") with pytest.raises(ValueError) as exc_info: @@ -47,7 +47,7 @@ def test_connect_invalid_implementation(): def test_connect_non_namespace_class(): - with patch('lance_namespace.namespace.importlib.import_module') as mock_import: + with patch('lance_namespace.importlib.import_module') as mock_import: mock_module = Mock() mock_module.NotANamespace = str mock_import.return_value = mock_module @@ -58,7 +58,8 @@ def test_connect_non_namespace_class(): assert "does not implement LanceNamespace interface" in str(exc_info.value) -def test_default_methods_raise_not_implemented(): +def test_default_methods_raise_unsupported(): + from lance_namespace import UnsupportedOperationError from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, DescribeNamespaceRequest, @@ -67,11 +68,11 @@ def test_default_methods_raise_not_implemented(): ns = MockNamespace() - with pytest.raises(NotImplementedError): + with pytest.raises(UnsupportedOperationError): ns.list_namespaces(ListNamespacesRequest()) - with pytest.raises(NotImplementedError): + with pytest.raises(UnsupportedOperationError): ns.describe_namespace(DescribeNamespaceRequest()) - with pytest.raises(NotImplementedError): - ns.create_namespace(CreateNamespaceRequest()) \ No newline at end of file + with pytest.raises(UnsupportedOperationError): + ns.create_namespace(CreateNamespaceRequest(id=["test"])) \ No newline at end of file diff --git a/python/tests/test_polaris.py b/python/tests/test_polaris.py new file mode 100644 index 0000000..fda3e72 --- /dev/null +++ b/python/tests/test_polaris.py @@ -0,0 +1,463 @@ +""" +Tests for Polaris Catalog namespace implementation. +""" + +import unittest +from unittest.mock import MagicMock, patch + +from lance_namespace_impls.polaris import ( + PolarisNamespace, + PolarisNamespaceConfig, +) +from lance_namespace_impls.rest_client import ( + RestClientException, + NamespaceNotFoundException, + NamespaceAlreadyExistsException, + TableNotFoundException, + TableAlreadyExistsException, + InvalidInputException, + InternalException, +) +from lance_namespace_urllib3_client.models import ( + ListNamespacesRequest, + CreateNamespaceRequest, + DescribeNamespaceRequest, + DropNamespaceRequest, + ListTablesRequest, + CreateEmptyTableRequest, + DescribeTableRequest, + DeregisterTableRequest, +) + + +class TestPolarisNamespaceConfig(unittest.TestCase): + """Test Polaris namespace configuration.""" + + def test_config_initialization(self): + """Test configuration initialization with required properties.""" + properties = { + "polaris.endpoint": "https://polaris.example.com", + "polaris.root": "/data/lance", + "polaris.auth_token": "test_token", + } + + config = PolarisNamespaceConfig(properties) + + self.assertEqual(config.endpoint, "https://polaris.example.com") + self.assertEqual(config.root, "/data/lance") + self.assertEqual(config.auth_token, "test_token") + + def test_config_defaults(self): + """Test configuration with default values.""" + properties = {"polaris.endpoint": "https://polaris.example.com"} + + config = PolarisNamespaceConfig(properties) + + self.assertEqual(config.root, "/tmp/lance") + self.assertIsNone(config.auth_token) + self.assertEqual(config.connect_timeout, 10000) + self.assertEqual(config.read_timeout, 30000) + self.assertEqual(config.max_retries, 3) + + def test_config_missing_endpoint(self): + """Test configuration fails without endpoint.""" + properties = {} + + with self.assertRaises(ValueError) as context: + PolarisNamespaceConfig(properties) + + self.assertIn("polaris.endpoint", str(context.exception)) + + def test_get_full_api_url(self): + """Test API URL generation.""" + properties = {"polaris.endpoint": "https://polaris.example.com/"} + config = PolarisNamespaceConfig(properties) + + self.assertEqual(config.get_full_api_url(), "https://polaris.example.com") + + +class TestPolarisNamespace(unittest.TestCase): + """Test Polaris namespace implementation.""" + + def setUp(self): + """Set up test fixtures.""" + self.properties = { + "polaris.endpoint": "https://polaris.example.com", + "polaris.root": "/data/lance", + } + + @patch("lance_namespace_impls.polaris.RestClient") + def test_namespace_id(self, mock_rest_client_class): + """Test namespace ID generation.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = PolarisNamespace(**self.properties) + ns_id = namespace.namespace_id() + + self.assertIn("PolarisNamespace", ns_id) + self.assertIn("polaris.example.com", ns_id) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_list_namespaces_top_level(self, mock_rest_client_class): + """Test listing top-level namespaces.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "namespaces": [["ns1"], ["ns2"], ["ns3"]] + } + + namespace = PolarisNamespace(**self.properties) + + request = ListNamespacesRequest() + request.id = [] + + response = namespace.list_namespaces(request) + + self.assertEqual(sorted(response.namespaces), ["ns1", "ns2", "ns3"]) + mock_client.get.assert_called_once_with("/namespaces") + + @patch("lance_namespace_impls.polaris.RestClient") + def test_list_namespaces_nested(self, mock_rest_client_class): + """Test listing nested namespaces.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "namespaces": [["parent", "child1"], ["parent", "child2"]] + } + + namespace = PolarisNamespace(**self.properties) + + request = ListNamespacesRequest() + request.id = ["parent"] + + response = namespace.list_namespaces(request) + + self.assertEqual(sorted(response.namespaces), ["parent.child1", "parent.child2"]) + mock_client.get.assert_called_once_with("/namespaces/parent/namespaces") + + @patch("lance_namespace_impls.polaris.RestClient") + def test_create_namespace(self, mock_rest_client_class): + """Test creating a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.post.return_value = {"properties": {"key": "value"}} + + namespace = PolarisNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = ["test_namespace"] + request.properties = {"key": "value"} + + response = namespace.create_namespace(request) + + self.assertEqual(response.properties, {"key": "value"}) + mock_client.post.assert_called_once() + + @patch("lance_namespace_impls.polaris.RestClient") + def test_create_namespace_already_exists(self, mock_rest_client_class): + """Test creating a namespace that already exists.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.post.side_effect = RestClientException( + "Conflict", status_code=409, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = ["existing_namespace"] + + with self.assertRaises(NamespaceAlreadyExistsException): + namespace.create_namespace(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_describe_namespace(self, mock_rest_client_class): + """Test describing a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"properties": {"key": "value"}} + + namespace = PolarisNamespace(**self.properties) + + request = DescribeNamespaceRequest() + request.id = ["test_namespace"] + + response = namespace.describe_namespace(request) + + self.assertEqual(response.properties, {"key": "value"}) + mock_client.get.assert_called_once_with("/namespaces/test_namespace") + + @patch("lance_namespace_impls.polaris.RestClient") + def test_describe_namespace_not_found(self, mock_rest_client_class): + """Test describing a namespace that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = RestClientException( + "Not found", status_code=404, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = DescribeNamespaceRequest() + request.id = ["nonexistent"] + + with self.assertRaises(NamespaceNotFoundException): + namespace.describe_namespace(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_drop_namespace(self, mock_rest_client_class): + """Test dropping a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = PolarisNamespace(**self.properties) + + request = DropNamespaceRequest() + request.id = ["test_namespace"] + + response = namespace.drop_namespace(request) + + self.assertIsNotNone(response) + mock_client.delete.assert_called_once_with("/namespaces/test_namespace") + + @patch("lance_namespace_impls.polaris.RestClient") + def test_drop_namespace_not_found(self, mock_rest_client_class): + """Test dropping a namespace that doesn't exist returns success.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.delete.side_effect = RestClientException( + "Not found", status_code=404, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = DropNamespaceRequest() + request.id = ["nonexistent"] + + response = namespace.drop_namespace(request) + + self.assertIsNotNone(response) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_list_tables(self, mock_rest_client_class): + """Test listing tables in a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "identifiers": [ + {"name": "table1"}, + {"name": "table2"}, + {"name": "table3"}, + ] + } + + namespace = PolarisNamespace(**self.properties) + + request = ListTablesRequest() + request.id = ["test_namespace"] + + response = namespace.list_tables(request) + + self.assertEqual(sorted(response.tables), ["table1", "table2", "table3"]) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_create_empty_table(self, mock_rest_client_class): + """Test creating an empty table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.post.return_value = {} + + namespace = PolarisNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["test_namespace", "test_table"] + request.location = None + + response = namespace.create_empty_table(request) + + self.assertEqual( + response.location, "/data/lance/test_namespace/test_table" + ) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_create_empty_table_with_location(self, mock_rest_client_class): + """Test creating an empty table with custom location.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.post.return_value = {} + + namespace = PolarisNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["test_namespace", "test_table"] + request.location = "/custom/path/test_table" + + response = namespace.create_empty_table(request) + + self.assertEqual(response.location, "/custom/path/test_table") + + @patch("lance_namespace_impls.polaris.RestClient") + def test_create_empty_table_already_exists(self, mock_rest_client_class): + """Test creating a table that already exists.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.post.side_effect = RestClientException( + "Conflict", status_code=409, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["test_namespace", "existing_table"] + + with self.assertRaises(TableAlreadyExistsException): + namespace.create_empty_table(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_describe_table(self, mock_rest_client_class): + """Test describing a table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "table": { + "format": "lance", + "base-location": "/data/lance/ns/table", + "properties": {"key": "value"}, + } + } + + namespace = PolarisNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["test_namespace", "test_table"] + + response = namespace.describe_table(request) + + self.assertEqual(response.location, "/data/lance/ns/table") + self.assertEqual(response.storage_options, {"key": "value"}) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_describe_table_not_lance(self, mock_rest_client_class): + """Test describing a table that is not a Lance table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "table": { + "format": "iceberg", + "base-location": "/data/iceberg/ns/table", + "properties": {}, + } + } + + namespace = PolarisNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["test_namespace", "test_table"] + + with self.assertRaises(InvalidInputException): + namespace.describe_table(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_describe_table_not_found(self, mock_rest_client_class): + """Test describing a table that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = RestClientException( + "Not found", status_code=404, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["test_namespace", "nonexistent"] + + with self.assertRaises(TableNotFoundException): + namespace.describe_table(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_deregister_table(self, mock_rest_client_class): + """Test deregistering a table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = { + "table": {"base-location": "/data/lance/ns/table"} + } + + namespace = PolarisNamespace(**self.properties) + + request = DeregisterTableRequest() + request.id = ["test_namespace", "test_table"] + + response = namespace.deregister_table(request) + + self.assertEqual(response.location, "/data/lance/ns/table") + mock_client.delete.assert_called_once() + + @patch("lance_namespace_impls.polaris.RestClient") + def test_deregister_table_not_found(self, mock_rest_client_class): + """Test deregistering a table that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = RestClientException( + "Not found", status_code=404, response_body="" + ) + + namespace = PolarisNamespace(**self.properties) + + request = DeregisterTableRequest() + request.id = ["test_namespace", "nonexistent"] + + with self.assertRaises(TableNotFoundException): + namespace.deregister_table(request) + + @patch("lance_namespace_impls.polaris.RestClient") + def test_close(self, mock_rest_client_class): + """Test closing the namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = PolarisNamespace(**self.properties) + namespace.close() + + mock_client.close.assert_called_once() + + def test_invalid_table_id(self): + """Test that table operations fail with invalid identifiers.""" + namespace = PolarisNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["only_namespace"] + + with self.assertRaises(InvalidInputException): + namespace.create_empty_table(request) + + def test_invalid_namespace_id(self): + """Test that namespace operations fail with empty identifiers.""" + namespace = PolarisNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = [] + + with self.assertRaises(InvalidInputException): + namespace.create_namespace(request) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/tests/test_schema.py b/python/tests/test_schema.py index 561ff73..3ebd100 100644 --- a/python/tests/test_schema.py +++ b/python/tests/test_schema.py @@ -4,7 +4,7 @@ import pytest import pyarrow as pa -from lance_namespace.schema import ( +from lance_namespace_impls.schema import ( convert_json_arrow_schema_to_pyarrow, convert_json_arrow_type_to_pyarrow, ) diff --git a/python/tests/test_unity.py b/python/tests/test_unity.py index cbfc672..ab159f4 100644 --- a/python/tests/test_unity.py +++ b/python/tests/test_unity.py @@ -10,16 +10,24 @@ import pyarrow as pa import pyarrow.ipc as ipc -from lance_namespace.unity import ( +from lance_namespace_impls.unity import ( UnityNamespace, UnityNamespaceConfig, - RestClient, - RestClientException, - LanceNamespaceException, SchemaInfo, TableInfo, ColumnInfo, ) +from lance_namespace_impls.rest_client import ( + RestClient, + RestClientException, + NamespaceException, + NamespaceNotFoundException, + NamespaceAlreadyExistsException, + TableNotFoundException, + TableAlreadyExistsException, + InvalidInputException, + InternalException, +) from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, CreateNamespaceRequest, @@ -97,72 +105,72 @@ def test_get_full_api_url(self): class TestRestClient(unittest.TestCase): """Test REST client functionality.""" - @patch('lance_namespace.unity.urllib3.PoolManager') + @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') def test_get_request(self, mock_pool_manager): """Test GET request.""" mock_http = MagicMock() mock_pool_manager.return_value = mock_http - + mock_response = MagicMock() mock_response.status = 200 mock_response.data = b'{"name": "test_schema"}' mock_http.request.return_value = mock_response - + client = RestClient("https://api.example.com") result = client.get("/schemas/test") - + self.assertEqual(result, {"name": "test_schema"}) mock_http.request.assert_called_once() - - @patch('lance_namespace.unity.urllib3.PoolManager') + + @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') def test_post_request(self, mock_pool_manager): """Test POST request.""" mock_http = MagicMock() mock_pool_manager.return_value = mock_http - + mock_response = MagicMock() mock_response.status = 201 mock_response.data = b'{"id": "123"}' mock_http.request.return_value = mock_response - + client = RestClient("https://api.example.com") result = client.post("/schemas", {"name": "test"}) - + self.assertEqual(result, {"id": "123"}) mock_http.request.assert_called_once() - - @patch('lance_namespace.unity.urllib3.PoolManager') + + @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') def test_delete_request(self, mock_pool_manager): """Test DELETE request.""" mock_http = MagicMock() mock_pool_manager.return_value = mock_http - + mock_response = MagicMock() mock_response.status = 204 mock_response.data = b'' mock_http.request.return_value = mock_response - + client = RestClient("https://api.example.com") client.delete("/schemas/test") - + mock_http.request.assert_called_once() - - @patch('lance_namespace.unity.urllib3.PoolManager') + + @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') def test_error_response(self, mock_pool_manager): """Test error response handling.""" mock_http = MagicMock() mock_pool_manager.return_value = mock_http - + mock_response = MagicMock() mock_response.status = 404 mock_response.data = b'{"error": "Not found"}' mock_http.request.return_value = mock_response - + client = RestClient("https://api.example.com") - + with self.assertRaises(RestClientException) as context: client.get("/schemas/test") - + self.assertEqual(context.exception.status_code, 404) self.assertIn("Not found", context.exception.response_body) @@ -178,7 +186,7 @@ def setUp(self): "unity.root": "/data/lance" } - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_list_namespaces_top_level(self, mock_rest_client_class): """Test listing top-level namespaces (catalogs).""" mock_client = MagicMock() @@ -194,7 +202,7 @@ def test_list_namespaces_top_level(self, mock_rest_client_class): self.assertEqual(response.namespaces, ["test_catalog"]) mock_client.get.assert_not_called() - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_list_namespaces_schemas(self, mock_rest_client_class): """Test listing schemas in a catalog.""" mock_client = MagicMock() @@ -220,7 +228,7 @@ def test_list_namespaces_schemas(self, mock_rest_client_class): params={'catalog_name': 'test_catalog'} ) - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_create_namespace(self, mock_rest_client_class): """Test creating a namespace.""" mock_client = MagicMock() @@ -243,52 +251,46 @@ def test_create_namespace(self, mock_rest_client_class): self.assertEqual(response.properties, {"key": "value"}) - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_describe_namespace(self, mock_rest_client_class): """Test describing a namespace.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_schema_info = SchemaInfo( name="test_schema", catalog_name="test_catalog", properties={"key": "value"} ) mock_client.get.return_value = mock_schema_info - + namespace = UnityNamespace(**self.properties) - + request = DescribeNamespaceRequest() request.id = ["test_catalog", "test_schema"] - + response = namespace.describe_namespace(request) - + self.assertEqual(response.properties, {"key": "value"}) - mock_client.get.assert_called_once_with( - "/schemas/test_catalog.test_schema", - response_class=SchemaInfo - ) + mock_client.get.assert_called_once() - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_drop_namespace(self, mock_rest_client_class): """Test dropping a namespace.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + namespace = UnityNamespace(**self.properties) - + request = DropNamespaceRequest() request.id = ["test_catalog", "test_schema"] - + response = namespace.drop_namespace(request) - + self.assertIsNotNone(response) - mock_client.delete.assert_called_once_with( - "/schemas/test_catalog.test_schema", - params={} - ) + mock_client.delete.assert_called_once() - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_list_tables(self, mock_rest_client_class): """Test listing tables in a namespace.""" mock_client = MagicMock() @@ -312,50 +314,23 @@ def test_list_tables(self, mock_rest_client_class): # Should only return Lance tables self.assertEqual(sorted(response.tables), ["table1", "table3"]) - @patch('lance_namespace.unity.lance') - @patch('lance_namespace.unity.RestClient') - def test_create_table(self, mock_rest_client_class, mock_lance): - """Test creating a table.""" + @patch('lance_namespace_impls.unity.RestClient') + def test_create_table_not_supported(self, mock_rest_client_class): + """Test that create_table raises NotImplementedError.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - - # Create test Arrow schema and IPC data - arrow_schema = pa.schema([ - pa.field("id", pa.int64()), - pa.field("name", pa.string()) - ]) - - # Create IPC stream data - buf = io.BytesIO() - writer = ipc.new_stream(buf, arrow_schema) - writer.close() - ipc_data = buf.getvalue() - - mock_table_info = TableInfo( - name="test_table", - catalog_name="test_catalog", - schema_name="test_schema", - table_type="EXTERNAL", - data_source_format="TEXT", - columns=[], - storage_location="/data/lance/test_catalog/test_schema/test_table", - properties={"table_type": "lance", "version": "0"} - ) - mock_client.post.return_value = mock_table_info - + namespace = UnityNamespace(**self.properties) - + request = CreateTableRequest() request.id = ["test_catalog", "test_schema", "test_table"] - request.properties = {"custom": "property"} - - response = namespace.create_table(request, ipc_data) - - self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - self.assertEqual(response.version, 1) - mock_lance.write_dataset.assert_called_once() + + with self.assertRaises(NotImplementedError) as context: + namespace.create_table(request, b"test_data") + + self.assertIn("create_table is not supported", str(context.exception)) - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.RestClient') def test_create_empty_table(self, mock_rest_client_class): """Test creating an empty table.""" mock_client = MagicMock() @@ -382,8 +357,8 @@ def test_create_empty_table(self, mock_rest_client_class): self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - @patch('lance_namespace.unity.lance') - @patch('lance_namespace.unity.RestClient') + @patch('lance_namespace_impls.unity.lance') + @patch('lance_namespace_impls.unity.RestClient') def test_describe_table(self, mock_rest_client_class, mock_lance): """Test describing a table.""" mock_client = MagicMock() @@ -412,41 +387,24 @@ def test_describe_table(self, mock_rest_client_class, mock_lance): request.id = ["test_catalog", "test_schema", "test_table"] response = namespace.describe_table(request) - + self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - self.assertEqual(response.properties, {"table_type": "lance"}) - @patch('lance_namespace.unity.os') - @patch('lance_namespace.unity.shutil') - @patch('lance_namespace.unity.RestClient') - def test_drop_table(self, mock_rest_client_class, mock_shutil, mock_os): - """Test dropping a table.""" + @patch('lance_namespace_impls.unity.RestClient') + def test_drop_table_not_supported(self, mock_rest_client_class): + """Test that drop_table raises NotImplementedError.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - - mock_table_info = TableInfo( - name="test_table", - catalog_name="test_catalog", - schema_name="test_schema", - table_type="EXTERNAL", - data_source_format="TEXT", - columns=[], - storage_location="/data/lance/test_catalog/test_schema/test_table", - properties={"table_type": "lance"} - ) - mock_client.get.return_value = mock_table_info - mock_os.path.exists.return_value = True - + namespace = UnityNamespace(**self.properties) - + request = DropTableRequest() request.id = ["test_catalog", "test_schema", "test_table"] - - response = namespace.drop_table(request) - - self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - mock_client.delete.assert_called_once_with("/tables/test_catalog.test_schema.test_table") - mock_shutil.rmtree.assert_called_once_with("/data/lance/test_catalog/test_schema/test_table") + + with self.assertRaises(NotImplementedError) as context: + namespace.drop_table(request) + + self.assertIn("drop_table is not supported", str(context.exception)) def test_arrow_type_conversion(self): """Test Arrow type to Unity type conversion.""" diff --git a/python/uv.lock b/python/uv.lock new file mode 100644 index 0000000..6a2cd24 --- /dev/null +++ b/python/uv.lock @@ -0,0 +1,818 @@ +version = 1 +revision = 3 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.11'", + "python_full_version < '3.11'", +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "boto3" +version = "1.42.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, + { name = "jmespath" }, + { name = "s3transfer" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/37/22c82e9d314d769a6eaf600ce5e08357927b5c6a614bfbeb1e7b7e7aa036/boto3-1.42.16.tar.gz", hash = "sha256:811391611db88c8a061f6e6fabbd7ca784ad9de04490a879f091cbaa9de7de74", size = 112834, upload-time = "2025-12-23T20:44:21.286Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/93/78d175e7d40941c4b608a6701a14215aeeb1db58499dbbc40467a6fd6116/boto3-1.42.16-py3-none-any.whl", hash = "sha256:37a43d42aebd06a8f93ee801ea1b7b5181ac42a30869ef403c9dadc160a748e5", size = 140574, upload-time = "2025-12-23T20:44:20.121Z" }, +] + +[[package]] +name = "botocore" +version = "1.42.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/eb/d91fb1fb288ba896392d68f89881f5f26bc5b51f8da28697c77f05bc44e8/botocore-1.42.16.tar.gz", hash = "sha256:29ee8555cd5d5023350405387cedcf3fe1c7f02fcb8060bf9e01602487482c25", size = 14914600, upload-time = "2025-12-23T20:44:11.025Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/98/c7c26ff399994e2b1119cc36027aaae46b9d646a49b70a82c2622e44c94b/botocore-1.42.16-py3-none-any.whl", hash = "sha256:b1f584a0f8645c12e07bf6ec9c18e05221a789f2a9b2d3c6291deb42f8c1c542", size = 14585775, upload-time = "2025-12-23T20:44:08.092Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/45/2c665ca77ec32ad67e25c77daf1cee28ee4558f3bc571cdbaf88a00b9f23/coverage-7.13.0.tar.gz", hash = "sha256:a394aa27f2d7ff9bc04cf703817773a59ad6dfbd577032e690f961d2460ee936", size = 820905, upload-time = "2025-12-08T13:14:38.055Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/08/bdd7ccca14096f7eb01412b87ac11e5d16e4cb54b6e328afc9dee8bdaec1/coverage-7.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:02d9fb9eccd48f6843c98a37bd6817462f130b86da8660461e8f5e54d4c06070", size = 217979, upload-time = "2025-12-08T13:12:14.505Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/d1302e3416298a28b5663ae1117546a745d9d19fde7e28402b2c5c3e2109/coverage-7.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:367449cf07d33dc216c083f2036bb7d976c6e4903ab31be400ad74ad9f85ce98", size = 218496, upload-time = "2025-12-08T13:12:16.237Z" }, + { url = "https://files.pythonhosted.org/packages/07/26/d36c354c8b2a320819afcea6bffe72839efd004b98d1d166b90801d49d57/coverage-7.13.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cdb3c9f8fef0a954c632f64328a3935988d33a6604ce4bf67ec3e39670f12ae5", size = 245237, upload-time = "2025-12-08T13:12:17.858Z" }, + { url = "https://files.pythonhosted.org/packages/91/52/be5e85631e0eec547873d8b08dd67a5f6b111ecfe89a86e40b89b0c1c61c/coverage-7.13.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d10fd186aac2316f9bbb46ef91977f9d394ded67050ad6d84d94ed6ea2e8e54e", size = 247061, upload-time = "2025-12-08T13:12:19.132Z" }, + { url = "https://files.pythonhosted.org/packages/0f/45/a5e8fa0caf05fbd8fa0402470377bff09cc1f026d21c05c71e01295e55ab/coverage-7.13.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f88ae3e69df2ab62fb0bc5219a597cb890ba5c438190ffa87490b315190bb33", size = 248928, upload-time = "2025-12-08T13:12:20.702Z" }, + { url = "https://files.pythonhosted.org/packages/f5/42/ffb5069b6fd1b95fae482e02f3fecf380d437dd5a39bae09f16d2e2e7e01/coverage-7.13.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4be718e51e86f553bcf515305a158a1cd180d23b72f07ae76d6017c3cc5d791", size = 245931, upload-time = "2025-12-08T13:12:22.243Z" }, + { url = "https://files.pythonhosted.org/packages/95/6e/73e809b882c2858f13e55c0c36e94e09ce07e6165d5644588f9517efe333/coverage-7.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a00d3a393207ae12f7c49bb1c113190883b500f48979abb118d8b72b8c95c032", size = 246968, upload-time = "2025-12-08T13:12:23.52Z" }, + { url = "https://files.pythonhosted.org/packages/87/08/64ebd9e64b6adb8b4a4662133d706fbaccecab972e0b3ccc23f64e2678ad/coverage-7.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a7b1cd820e1b6116f92c6128f1188e7afe421c7e1b35fa9836b11444e53ebd9", size = 244972, upload-time = "2025-12-08T13:12:24.781Z" }, + { url = "https://files.pythonhosted.org/packages/12/97/f4d27c6fe0cb375a5eced4aabcaef22de74766fb80a3d5d2015139e54b22/coverage-7.13.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:37eee4e552a65866f15dedd917d5e5f3d59805994260720821e2c1b51ac3248f", size = 245241, upload-time = "2025-12-08T13:12:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/0c/94/42f8ae7f633bf4c118bf1038d80472f9dade88961a466f290b81250f7ab7/coverage-7.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62d7c4f13102148c78d7353c6052af6d899a7f6df66a32bddcc0c0eb7c5326f8", size = 245847, upload-time = "2025-12-08T13:12:29.337Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2f/6369ca22b6b6d933f4f4d27765d313d8914cc4cce84f82a16436b1a233db/coverage-7.13.0-cp310-cp310-win32.whl", hash = "sha256:24e4e56304fdb56f96f80eabf840eab043b3afea9348b88be680ec5986780a0f", size = 220573, upload-time = "2025-12-08T13:12:30.905Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dc/a6a741e519acceaeccc70a7f4cfe5d030efc4b222595f0677e101af6f1f3/coverage-7.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:74c136e4093627cf04b26a35dab8cbfc9b37c647f0502fc313376e11726ba303", size = 221509, upload-time = "2025-12-08T13:12:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dc/888bf90d8b1c3d0b4020a40e52b9f80957d75785931ec66c7dfaccc11c7d/coverage-7.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0dfa3855031070058add1a59fdfda0192fd3e8f97e7c81de0596c145dea51820", size = 218104, upload-time = "2025-12-08T13:12:33.333Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ea/069d51372ad9c380214e86717e40d1a743713a2af191cfba30a0911b0a4a/coverage-7.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fdb6f54f38e334db97f72fa0c701e66d8479af0bc3f9bfb5b90f1c30f54500f", size = 218606, upload-time = "2025-12-08T13:12:34.498Z" }, + { url = "https://files.pythonhosted.org/packages/68/09/77b1c3a66c2aa91141b6c4471af98e5b1ed9b9e6d17255da5eb7992299e3/coverage-7.13.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7e442c013447d1d8d195be62852270b78b6e255b79b8675bad8479641e21fd96", size = 248999, upload-time = "2025-12-08T13:12:36.02Z" }, + { url = "https://files.pythonhosted.org/packages/0a/32/2e2f96e9d5691eaf1181d9040f850b8b7ce165ea10810fd8e2afa534cef7/coverage-7.13.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ed5630d946859de835a85e9a43b721123a8a44ec26e2830b296d478c7fd4259", size = 250925, upload-time = "2025-12-08T13:12:37.221Z" }, + { url = "https://files.pythonhosted.org/packages/7b/45/b88ddac1d7978859b9a39a8a50ab323186148f1d64bc068f86fc77706321/coverage-7.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f15a931a668e58087bc39d05d2b4bf4b14ff2875b49c994bbdb1c2217a8daeb", size = 253032, upload-time = "2025-12-08T13:12:38.763Z" }, + { url = "https://files.pythonhosted.org/packages/71/cb/e15513f94c69d4820a34b6bf3d2b1f9f8755fa6021be97c7065442d7d653/coverage-7.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:30a3a201a127ea57f7e14ba43c93c9c4be8b7d17a26e03bb49e6966d019eede9", size = 249134, upload-time = "2025-12-08T13:12:40.382Z" }, + { url = "https://files.pythonhosted.org/packages/09/61/d960ff7dc9e902af3310ce632a875aaa7860f36d2bc8fc8b37ee7c1b82a5/coverage-7.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a485ff48fbd231efa32d58f479befce52dcb6bfb2a88bb7bf9a0b89b1bc8030", size = 250731, upload-time = "2025-12-08T13:12:41.992Z" }, + { url = "https://files.pythonhosted.org/packages/98/34/c7c72821794afc7c7c2da1db8f00c2c98353078aa7fb6b5ff36aac834b52/coverage-7.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22486cdafba4f9e471c816a2a5745337742a617fef68e890d8baf9f3036d7833", size = 248795, upload-time = "2025-12-08T13:12:43.331Z" }, + { url = "https://files.pythonhosted.org/packages/0a/5b/e0f07107987a43b2def9aa041c614ddb38064cbf294a71ef8c67d43a0cdd/coverage-7.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:263c3dbccc78e2e331e59e90115941b5f53e85cfcc6b3b2fbff1fd4e3d2c6ea8", size = 248514, upload-time = "2025-12-08T13:12:44.546Z" }, + { url = "https://files.pythonhosted.org/packages/71/c2/c949c5d3b5e9fc6dd79e1b73cdb86a59ef14f3709b1d72bf7668ae12e000/coverage-7.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5330fa0cc1f5c3c4c3bb8e101b742025933e7848989370a1d4c8c5e401ea753", size = 249424, upload-time = "2025-12-08T13:12:45.759Z" }, + { url = "https://files.pythonhosted.org/packages/11/f1/bbc009abd6537cec0dffb2cc08c17a7f03de74c970e6302db4342a6e05af/coverage-7.13.0-cp311-cp311-win32.whl", hash = "sha256:0f4872f5d6c54419c94c25dd6ae1d015deeb337d06e448cd890a1e89a8ee7f3b", size = 220597, upload-time = "2025-12-08T13:12:47.378Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/d9977f2fb51c10fbaed0718ce3d0a8541185290b981f73b1d27276c12d91/coverage-7.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51a202e0f80f241ccb68e3e26e19ab5b3bf0f813314f2c967642f13ebcf1ddfe", size = 221536, upload-time = "2025-12-08T13:12:48.7Z" }, + { url = "https://files.pythonhosted.org/packages/be/ad/3fcf43fd96fb43e337a3073dea63ff148dcc5c41ba7a14d4c7d34efb2216/coverage-7.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:d2a9d7f1c11487b1c69367ab3ac2d81b9b3721f097aa409a3191c3e90f8f3dd7", size = 220206, upload-time = "2025-12-08T13:12:50.365Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f1/2619559f17f31ba00fc40908efd1fbf1d0a5536eb75dc8341e7d660a08de/coverage-7.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0b3d67d31383c4c68e19a88e28fc4c2e29517580f1b0ebec4a069d502ce1e0bf", size = 218274, upload-time = "2025-12-08T13:12:52.095Z" }, + { url = "https://files.pythonhosted.org/packages/2b/11/30d71ae5d6e949ff93b2a79a2c1b4822e00423116c5c6edfaeef37301396/coverage-7.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:581f086833d24a22c89ae0fe2142cfaa1c92c930adf637ddf122d55083fb5a0f", size = 218638, upload-time = "2025-12-08T13:12:53.418Z" }, + { url = "https://files.pythonhosted.org/packages/79/c2/fce80fc6ded8d77e53207489d6065d0fed75db8951457f9213776615e0f5/coverage-7.13.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0a3a30f0e257df382f5f9534d4ce3d4cf06eafaf5192beb1a7bd066cb10e78fb", size = 250129, upload-time = "2025-12-08T13:12:54.744Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b6/51b5d1eb6fcbb9a1d5d6984e26cbe09018475c2922d554fd724dd0f056ee/coverage-7.13.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:583221913fbc8f53b88c42e8dbb8fca1d0f2e597cb190ce45916662b8b9d9621", size = 252885, upload-time = "2025-12-08T13:12:56.401Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/972a5affea41de798691ab15d023d3530f9f56a72e12e243f35031846ff7/coverage-7.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f5d9bd30756fff3e7216491a0d6d520c448d5124d3d8e8f56446d6412499e74", size = 253974, upload-time = "2025-12-08T13:12:57.718Z" }, + { url = "https://files.pythonhosted.org/packages/8a/56/116513aee860b2c7968aa3506b0f59b22a959261d1dbf3aea7b4450a7520/coverage-7.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a23e5a1f8b982d56fa64f8e442e037f6ce29322f1f9e6c2344cd9e9f4407ee57", size = 250538, upload-time = "2025-12-08T13:12:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/d6/75/074476d64248fbadf16dfafbf93fdcede389ec821f74ca858d7c87d2a98c/coverage-7.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b01c22bc74a7fb44066aaf765224c0d933ddf1f5047d6cdfe4795504a4493f8", size = 251912, upload-time = "2025-12-08T13:13:00.604Z" }, + { url = "https://files.pythonhosted.org/packages/f2/d2/aa4f8acd1f7c06024705c12609d8698c51b27e4d635d717cd1934c9668e2/coverage-7.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:898cce66d0836973f48dda4e3514d863d70142bdf6dfab932b9b6a90ea5b222d", size = 250054, upload-time = "2025-12-08T13:13:01.892Z" }, + { url = "https://files.pythonhosted.org/packages/19/98/8df9e1af6a493b03694a1e8070e024e7d2cdc77adedc225a35e616d505de/coverage-7.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:3ab483ea0e251b5790c2aac03acde31bff0c736bf8a86829b89382b407cd1c3b", size = 249619, upload-time = "2025-12-08T13:13:03.236Z" }, + { url = "https://files.pythonhosted.org/packages/d8/71/f8679231f3353018ca66ef647fa6fe7b77e6bff7845be54ab84f86233363/coverage-7.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d84e91521c5e4cb6602fe11ece3e1de03b2760e14ae4fcf1a4b56fa3c801fcd", size = 251496, upload-time = "2025-12-08T13:13:04.511Z" }, + { url = "https://files.pythonhosted.org/packages/04/86/9cb406388034eaf3c606c22094edbbb82eea1fa9d20c0e9efadff20d0733/coverage-7.13.0-cp312-cp312-win32.whl", hash = "sha256:193c3887285eec1dbdb3f2bd7fbc351d570ca9c02ca756c3afbc71b3c98af6ef", size = 220808, upload-time = "2025-12-08T13:13:06.422Z" }, + { url = "https://files.pythonhosted.org/packages/1c/59/af483673df6455795daf5f447c2f81a3d2fcfc893a22b8ace983791f6f34/coverage-7.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:4f3e223b2b2db5e0db0c2b97286aba0036ca000f06aca9b12112eaa9af3d92ae", size = 221616, upload-time = "2025-12-08T13:13:07.95Z" }, + { url = "https://files.pythonhosted.org/packages/64/b0/959d582572b30a6830398c60dd419c1965ca4b5fb38ac6b7093a0d50ca8d/coverage-7.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:086cede306d96202e15a4b77ace8472e39d9f4e5f9fd92dd4fecdfb2313b2080", size = 220261, upload-time = "2025-12-08T13:13:09.581Z" }, + { url = "https://files.pythonhosted.org/packages/7c/cc/bce226595eb3bf7d13ccffe154c3c487a22222d87ff018525ab4dd2e9542/coverage-7.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:28ee1c96109974af104028a8ef57cec21447d42d0e937c0275329272e370ebcf", size = 218297, upload-time = "2025-12-08T13:13:10.977Z" }, + { url = "https://files.pythonhosted.org/packages/3b/9f/73c4d34600aae03447dff3d7ad1d0ac649856bfb87d1ca7d681cfc913f9e/coverage-7.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d1e97353dcc5587b85986cda4ff3ec98081d7e84dd95e8b2a6d59820f0545f8a", size = 218673, upload-time = "2025-12-08T13:13:12.562Z" }, + { url = "https://files.pythonhosted.org/packages/63/ab/8fa097db361a1e8586535ae5073559e6229596b3489ec3ef2f5b38df8cb2/coverage-7.13.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:99acd4dfdfeb58e1937629eb1ab6ab0899b131f183ee5f23e0b5da5cba2fec74", size = 249652, upload-time = "2025-12-08T13:13:13.909Z" }, + { url = "https://files.pythonhosted.org/packages/90/3a/9bfd4de2ff191feb37ef9465855ca56a6f2f30a3bca172e474130731ac3d/coverage-7.13.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff45e0cd8451e293b63ced93161e189780baf444119391b3e7d25315060368a6", size = 252251, upload-time = "2025-12-08T13:13:15.553Z" }, + { url = "https://files.pythonhosted.org/packages/df/61/b5d8105f016e1b5874af0d7c67542da780ccd4a5f2244a433d3e20ceb1ad/coverage-7.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4f72a85316d8e13234cafe0a9f81b40418ad7a082792fa4165bd7d45d96066b", size = 253492, upload-time = "2025-12-08T13:13:16.849Z" }, + { url = "https://files.pythonhosted.org/packages/f3/b8/0fad449981803cc47a4694768b99823fb23632150743f9c83af329bb6090/coverage-7.13.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11c21557d0e0a5a38632cbbaca5f008723b26a89d70db6315523df6df77d6232", size = 249850, upload-time = "2025-12-08T13:13:18.142Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e9/8d68337c3125014d918cf4327d5257553a710a2995a6a6de2ac77e5aa429/coverage-7.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76541dc8d53715fb4f7a3a06b34b0dc6846e3c69bc6204c55653a85dd6220971", size = 251633, upload-time = "2025-12-08T13:13:19.56Z" }, + { url = "https://files.pythonhosted.org/packages/55/14/d4112ab26b3a1bc4b3c1295d8452dcf399ed25be4cf649002fb3e64b2d93/coverage-7.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6e9e451dee940a86789134b6b0ffbe31c454ade3b849bb8a9d2cca2541a8e91d", size = 249586, upload-time = "2025-12-08T13:13:20.883Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a9/22b0000186db663b0d82f86c2f1028099ae9ac202491685051e2a11a5218/coverage-7.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:5c67dace46f361125e6b9cace8fe0b729ed8479f47e70c89b838d319375c8137", size = 249412, upload-time = "2025-12-08T13:13:22.22Z" }, + { url = "https://files.pythonhosted.org/packages/a1/2e/42d8e0d9e7527fba439acdc6ed24a2b97613b1dc85849b1dd935c2cffef0/coverage-7.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f59883c643cb19630500f57016f76cfdcd6845ca8c5b5ea1f6e17f74c8e5f511", size = 251191, upload-time = "2025-12-08T13:13:23.899Z" }, + { url = "https://files.pythonhosted.org/packages/a4/af/8c7af92b1377fd8860536aadd58745119252aaaa71a5213e5a8e8007a9f5/coverage-7.13.0-cp313-cp313-win32.whl", hash = "sha256:58632b187be6f0be500f553be41e277712baa278147ecb7559983c6d9faf7ae1", size = 220829, upload-time = "2025-12-08T13:13:25.182Z" }, + { url = "https://files.pythonhosted.org/packages/58/f9/725e8bf16f343d33cbe076c75dc8370262e194ff10072c0608b8e5cf33a3/coverage-7.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:73419b89f812f498aca53f757dd834919b48ce4799f9d5cad33ca0ae442bdb1a", size = 221640, upload-time = "2025-12-08T13:13:26.836Z" }, + { url = "https://files.pythonhosted.org/packages/8a/ff/e98311000aa6933cc79274e2b6b94a2fe0fe3434fca778eba82003675496/coverage-7.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:eb76670874fdd6091eedcc856128ee48c41a9bbbb9c3f1c7c3cf169290e3ffd6", size = 220269, upload-time = "2025-12-08T13:13:28.116Z" }, + { url = "https://files.pythonhosted.org/packages/cf/cf/bbaa2e1275b300343ea865f7d424cc0a2e2a1df6925a070b2b2d5d765330/coverage-7.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6e63ccc6e0ad8986386461c3c4b737540f20426e7ec932f42e030320896c311a", size = 218990, upload-time = "2025-12-08T13:13:29.463Z" }, + { url = "https://files.pythonhosted.org/packages/21/1d/82f0b3323b3d149d7672e7744c116e9c170f4957e0c42572f0366dbb4477/coverage-7.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:494f5459ffa1bd45e18558cd98710c36c0b8fbfa82a5eabcbe671d80ecffbfe8", size = 219340, upload-time = "2025-12-08T13:13:31.524Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e3/fe3fd4702a3832a255f4d43013eacb0ef5fc155a5960ea9269d8696db28b/coverage-7.13.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:06cac81bf10f74034e055e903f5f946e3e26fc51c09fc9f584e4a1605d977053", size = 260638, upload-time = "2025-12-08T13:13:32.965Z" }, + { url = "https://files.pythonhosted.org/packages/ad/01/63186cb000307f2b4da463f72af9b85d380236965574c78e7e27680a2593/coverage-7.13.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f2ffc92b46ed6e6760f1d47a71e56b5664781bc68986dbd1836b2b70c0ce2071", size = 262705, upload-time = "2025-12-08T13:13:34.378Z" }, + { url = "https://files.pythonhosted.org/packages/7c/a1/c0dacef0cc865f2455d59eed3548573ce47ed603205ffd0735d1d78b5906/coverage-7.13.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0602f701057c6823e5db1b74530ce85f17c3c5be5c85fc042ac939cbd909426e", size = 265125, upload-time = "2025-12-08T13:13:35.73Z" }, + { url = "https://files.pythonhosted.org/packages/ef/92/82b99223628b61300bd382c205795533bed021505eab6dd86e11fb5d7925/coverage-7.13.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:25dc33618d45456ccb1d37bce44bc78cf269909aa14c4db2e03d63146a8a1493", size = 259844, upload-time = "2025-12-08T13:13:37.69Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2c/89b0291ae4e6cd59ef042708e1c438e2290f8c31959a20055d8768349ee2/coverage-7.13.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:71936a8b3b977ddd0b694c28c6a34f4fff2e9dd201969a4ff5d5fc7742d614b0", size = 262700, upload-time = "2025-12-08T13:13:39.525Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f9/a5f992efae1996245e796bae34ceb942b05db275e4b34222a9a40b9fbd3b/coverage-7.13.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:936bc20503ce24770c71938d1369461f0c5320830800933bc3956e2a4ded930e", size = 260321, upload-time = "2025-12-08T13:13:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/4c/89/a29f5d98c64fedbe32e2ac3c227fbf78edc01cc7572eee17d61024d89889/coverage-7.13.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:af0a583efaacc52ae2521f8d7910aff65cdb093091d76291ac5820d5e947fc1c", size = 259222, upload-time = "2025-12-08T13:13:43.282Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c3/940fe447aae302a6701ee51e53af7e08b86ff6eed7631e5740c157ee22b9/coverage-7.13.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f1c23e24a7000da892a312fb17e33c5f94f8b001de44b7cf8ba2e36fbd15859e", size = 261411, upload-time = "2025-12-08T13:13:44.72Z" }, + { url = "https://files.pythonhosted.org/packages/eb/31/12a4aec689cb942a89129587860ed4d0fd522d5fda81237147fde554b8ae/coverage-7.13.0-cp313-cp313t-win32.whl", hash = "sha256:5f8a0297355e652001015e93be345ee54393e45dc3050af4a0475c5a2b767d46", size = 221505, upload-time = "2025-12-08T13:13:46.332Z" }, + { url = "https://files.pythonhosted.org/packages/65/8c/3b5fe3259d863572d2b0827642c50c3855d26b3aefe80bdc9eba1f0af3b0/coverage-7.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:6abb3a4c52f05e08460bd9acf04fec027f8718ecaa0d09c40ffbc3fbd70ecc39", size = 222569, upload-time = "2025-12-08T13:13:47.79Z" }, + { url = "https://files.pythonhosted.org/packages/b0/39/f71fa8316a96ac72fc3908839df651e8eccee650001a17f2c78cdb355624/coverage-7.13.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3ad968d1e3aa6ce5be295ab5fe3ae1bf5bb4769d0f98a80a0252d543a2ef2e9e", size = 220841, upload-time = "2025-12-08T13:13:49.243Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4b/9b54bedda55421449811dcd5263a2798a63f48896c24dfb92b0f1b0845bd/coverage-7.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:453b7ec753cf5e4356e14fe858064e5520c460d3bbbcb9c35e55c0d21155c256", size = 218343, upload-time = "2025-12-08T13:13:50.811Z" }, + { url = "https://files.pythonhosted.org/packages/59/df/c3a1f34d4bba2e592c8979f924da4d3d4598b0df2392fbddb7761258e3dc/coverage-7.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:af827b7cbb303e1befa6c4f94fd2bf72f108089cfa0f8abab8f4ca553cf5ca5a", size = 218672, upload-time = "2025-12-08T13:13:52.284Z" }, + { url = "https://files.pythonhosted.org/packages/07/62/eec0659e47857698645ff4e6ad02e30186eb8afd65214fd43f02a76537cb/coverage-7.13.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9987a9e4f8197a1000280f7cc089e3ea2c8b3c0a64d750537809879a7b4ceaf9", size = 249715, upload-time = "2025-12-08T13:13:53.791Z" }, + { url = "https://files.pythonhosted.org/packages/23/2d/3c7ff8b2e0e634c1f58d095f071f52ed3c23ff25be524b0ccae8b71f99f8/coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19", size = 252225, upload-time = "2025-12-08T13:13:55.274Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ac/fb03b469d20e9c9a81093575003f959cf91a4a517b783aab090e4538764b/coverage-7.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2bdb3babb74079f021696cb46b8bb5f5661165c385d3a238712b031a12355be", size = 253559, upload-time = "2025-12-08T13:13:57.161Z" }, + { url = "https://files.pythonhosted.org/packages/29/62/14afa9e792383c66cc0a3b872a06ded6e4ed1079c7d35de274f11d27064e/coverage-7.13.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7464663eaca6adba4175f6c19354feea61ebbdd735563a03d1e472c7072d27bb", size = 249724, upload-time = "2025-12-08T13:13:58.692Z" }, + { url = "https://files.pythonhosted.org/packages/31/b7/333f3dab2939070613696ab3ee91738950f0467778c6e5a5052e840646b7/coverage-7.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8069e831f205d2ff1f3d355e82f511eb7c5522d7d413f5db5756b772ec8697f8", size = 251582, upload-time = "2025-12-08T13:14:00.642Z" }, + { url = "https://files.pythonhosted.org/packages/81/cb/69162bda9381f39b2287265d7e29ee770f7c27c19f470164350a38318764/coverage-7.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:6fb2d5d272341565f08e962cce14cdf843a08ac43bd621783527adb06b089c4b", size = 249538, upload-time = "2025-12-08T13:14:02.556Z" }, + { url = "https://files.pythonhosted.org/packages/e0/76/350387b56a30f4970abe32b90b2a434f87d29f8b7d4ae40d2e8a85aacfb3/coverage-7.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5e70f92ef89bac1ac8a99b3324923b4749f008fdbd7aa9cb35e01d7a284a04f9", size = 249349, upload-time = "2025-12-08T13:14:04.015Z" }, + { url = "https://files.pythonhosted.org/packages/86/0d/7f6c42b8d59f4c7e43ea3059f573c0dcfed98ba46eb43c68c69e52ae095c/coverage-7.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4b5de7d4583e60d5fd246dd57fcd3a8aa23c6e118a8c72b38adf666ba8e7e927", size = 251011, upload-time = "2025-12-08T13:14:05.505Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f1/4bb2dff379721bb0b5c649d5c5eaf438462cad824acf32eb1b7ca0c7078e/coverage-7.13.0-cp314-cp314-win32.whl", hash = "sha256:a6c6e16b663be828a8f0b6c5027d36471d4a9f90d28444aa4ced4d48d7d6ae8f", size = 221091, upload-time = "2025-12-08T13:14:07.127Z" }, + { url = "https://files.pythonhosted.org/packages/ba/44/c239da52f373ce379c194b0ee3bcc121020e397242b85f99e0afc8615066/coverage-7.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:0900872f2fdb3ee5646b557918d02279dc3af3dfb39029ac4e945458b13f73bc", size = 221904, upload-time = "2025-12-08T13:14:08.542Z" }, + { url = "https://files.pythonhosted.org/packages/89/1f/b9f04016d2a29c2e4a0307baefefad1a4ec5724946a2b3e482690486cade/coverage-7.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:3a10260e6a152e5f03f26db4a407c4c62d3830b9af9b7c0450b183615f05d43b", size = 220480, upload-time = "2025-12-08T13:14:10.958Z" }, + { url = "https://files.pythonhosted.org/packages/16/d4/364a1439766c8e8647860584171c36010ca3226e6e45b1753b1b249c5161/coverage-7.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9097818b6cc1cfb5f174e3263eba4a62a17683bcfe5c4b5d07f4c97fa51fbf28", size = 219074, upload-time = "2025-12-08T13:14:13.345Z" }, + { url = "https://files.pythonhosted.org/packages/ce/f4/71ba8be63351e099911051b2089662c03d5671437a0ec2171823c8e03bec/coverage-7.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0018f73dfb4301a89292c73be6ba5f58722ff79f51593352759c1790ded1cabe", size = 219342, upload-time = "2025-12-08T13:14:15.02Z" }, + { url = "https://files.pythonhosted.org/packages/5e/25/127d8ed03d7711a387d96f132589057213e3aef7475afdaa303412463f22/coverage-7.13.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:166ad2a22ee770f5656e1257703139d3533b4a0b6909af67c6b4a3adc1c98657", size = 260713, upload-time = "2025-12-08T13:14:16.907Z" }, + { url = "https://files.pythonhosted.org/packages/fd/db/559fbb6def07d25b2243663b46ba9eb5a3c6586c0c6f4e62980a68f0ee1c/coverage-7.13.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f6aaef16d65d1787280943f1c8718dc32e9cf141014e4634d64446702d26e0ff", size = 262825, upload-time = "2025-12-08T13:14:18.68Z" }, + { url = "https://files.pythonhosted.org/packages/37/99/6ee5bf7eff884766edb43bd8736b5e1c5144d0fe47498c3779326fe75a35/coverage-7.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e999e2dcc094002d6e2c7bbc1fb85b58ba4f465a760a8014d97619330cdbbbf3", size = 265233, upload-time = "2025-12-08T13:14:20.55Z" }, + { url = "https://files.pythonhosted.org/packages/d8/90/92f18fe0356ea69e1f98f688ed80cec39f44e9f09a1f26a1bbf017cc67f2/coverage-7.13.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:00c3d22cf6fb1cf3bf662aaaa4e563be8243a5ed2630339069799835a9cc7f9b", size = 259779, upload-time = "2025-12-08T13:14:22.367Z" }, + { url = "https://files.pythonhosted.org/packages/90/5d/b312a8b45b37a42ea7d27d7d3ff98ade3a6c892dd48d1d503e773503373f/coverage-7.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22ccfe8d9bb0d6134892cbe1262493a8c70d736b9df930f3f3afae0fe3ac924d", size = 262700, upload-time = "2025-12-08T13:14:24.309Z" }, + { url = "https://files.pythonhosted.org/packages/63/f8/b1d0de5c39351eb71c366f872376d09386640840a2e09b0d03973d791e20/coverage-7.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9372dff5ea15930fea0445eaf37bbbafbc771a49e70c0aeed8b4e2c2614cc00e", size = 260302, upload-time = "2025-12-08T13:14:26.068Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7c/d42f4435bc40c55558b3109a39e2d456cddcec37434f62a1f1230991667a/coverage-7.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:69ac2c492918c2461bc6ace42d0479638e60719f2a4ef3f0815fa2df88e9f940", size = 259136, upload-time = "2025-12-08T13:14:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d3/23413241dc04d47cfe19b9a65b32a2edd67ecd0b817400c2843ebc58c847/coverage-7.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:739c6c051a7540608d097b8e13c76cfa85263ced467168dc6b477bae3df7d0e2", size = 261467, upload-time = "2025-12-08T13:14:29.09Z" }, + { url = "https://files.pythonhosted.org/packages/13/e6/6e063174500eee216b96272c0d1847bf215926786f85c2bd024cf4d02d2f/coverage-7.13.0-cp314-cp314t-win32.whl", hash = "sha256:fe81055d8c6c9de76d60c94ddea73c290b416e061d40d542b24a5871bad498b7", size = 221875, upload-time = "2025-12-08T13:14:31.106Z" }, + { url = "https://files.pythonhosted.org/packages/3b/46/f4fb293e4cbe3620e3ac2a3e8fd566ed33affb5861a9b20e3dd6c1896cbc/coverage-7.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:445badb539005283825959ac9fa4a28f712c214b65af3a2c464f1adc90f5fcbc", size = 222982, upload-time = "2025-12-08T13:14:33.1Z" }, + { url = "https://files.pythonhosted.org/packages/68/62/5b3b9018215ed9733fbd1ae3b2ed75c5de62c3b55377a52cae732e1b7805/coverage-7.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:de7f6748b890708578fc4b7bb967d810aeb6fcc9bff4bb77dbca77dab2f9df6a", size = 221016, upload-time = "2025-12-08T13:14:34.601Z" }, + { url = "https://files.pythonhosted.org/packages/8d/4c/1968f32fb9a2604645827e11ff84a31e59d532e01995f904723b4f5328b3/coverage-7.13.0-py3-none-any.whl", hash = "sha256:850d2998f380b1e266459ca5b47bc9e7daf9af1d070f66317972f382d46f1904", size = 210068, upload-time = "2025-12-08T13:14:36.236Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, +] + +[[package]] +name = "hive-metastore-client" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "thrift" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/ed/f15d3f3e4f3676368993beedde77f499456a64debc7fd244e9278f5b9631/hive_metastore_client-1.0.9.tar.gz", hash = "sha256:b7e00a7cbdd8b2907cb68a219b086f1dbcbeb2010d8c0b530c99c961c4512fe9", size = 122852, upload-time = "2021-08-23T17:55:28.623Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/40/1dc3ced1f1487cb298a465a0c30685569058b912d554e696394837430017/hive_metastore_client-1.0.9-py3-none-any.whl", hash = "sha256:62a6657804a772398574bba64d46cd7bff10babb7bdc601abe1118ca916810a5", size = 137883, upload-time = "2021-08-23T17:55:27.117Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "jmespath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843, upload-time = "2022-06-17T18:00:12.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256, upload-time = "2022-06-17T18:00:10.251Z" }, +] + +[[package]] +name = "lance-namespace" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lance-namespace-urllib3-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/8d/b117539252afc81b0fb94301e5543516af8594a70242ef247bc88c03cbdc/lance_namespace-0.4.0.tar.gz", hash = "sha256:aedfb5f4413ead9c5f0d2a351fe47b0b68a1dec0dd4331a88f54bce3491f630f", size = 9827, upload-time = "2025-12-21T16:07:51.349Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/fe/edbeb9ae7408685e90b2f0609c2f84bc3ef2f65d82bb4dce394de6d9c317/lance_namespace-0.4.0-py3-none-any.whl", hash = "sha256:7d91ee199a9864535ea17bd41787726c06b7ec8efbf06f7275bc54ea9998264f", size = 11701, upload-time = "2025-12-21T16:07:50.368Z" }, +] + +[[package]] +name = "lance-namespace-impls" +version = "0.0.1" +source = { editable = "." } +dependencies = [ + { name = "lance-namespace-urllib3-client" }, + { name = "pyarrow" }, + { name = "pylance" }, + { name = "typing-extensions" }, +] + +[package.optional-dependencies] +all = [ + { name = "boto3" }, + { name = "botocore" }, + { name = "hive-metastore-client" }, + { name = "thrift" }, +] +dev = [ + { name = "pytest" }, + { name = "pytest-cov" }, +] +glue = [ + { name = "boto3" }, + { name = "botocore" }, +] +hive2 = [ + { name = "hive-metastore-client" }, + { name = "thrift" }, +] +hive3 = [ + { name = "hive-metastore-client" }, + { name = "thrift" }, +] + +[package.metadata] +requires-dist = [ + { name = "boto3", marker = "extra == 'all'", specifier = ">=1.35.0" }, + { name = "boto3", marker = "extra == 'glue'", specifier = ">=1.35.0" }, + { name = "botocore", marker = "extra == 'all'", specifier = ">=1.35.0" }, + { name = "botocore", marker = "extra == 'glue'", specifier = ">=1.35.0" }, + { name = "hive-metastore-client", marker = "extra == 'all'", specifier = ">=1.0.0" }, + { name = "hive-metastore-client", marker = "extra == 'hive2'", specifier = ">=1.0.0" }, + { name = "hive-metastore-client", marker = "extra == 'hive3'", specifier = ">=1.0.0" }, + { name = "lance-namespace-urllib3-client", specifier = ">=0.0.21" }, + { name = "pyarrow", specifier = ">=15.0.0" }, + { name = "pylance", specifier = ">=0.26.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.0.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.0.0" }, + { name = "thrift", marker = "extra == 'all'", specifier = ">=0.13.0" }, + { name = "thrift", marker = "extra == 'hive2'", specifier = ">=0.13.0" }, + { name = "thrift", marker = "extra == 'hive3'", specifier = ">=0.13.0" }, + { name = "typing-extensions", specifier = ">=4.5.0" }, +] +provides-extras = ["glue", "hive2", "hive3", "unity", "all", "dev"] + +[[package]] +name = "lance-namespace-urllib3-client" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "typing-extensions" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/a2/53643e7ea756cd8c4275219f555a554db340d1e4e7366df39a79d9bd092d/lance_namespace_urllib3_client-0.4.0.tar.gz", hash = "sha256:896bf9336f5b14f5acc0d45ca956e291e0fcc2a0e56c1efe52723c23ae3a3296", size = 154577, upload-time = "2025-12-21T16:07:53.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/1f/050c1ed613b0ec017fa3b85d35d52658ead1158d95a092c1b83578d39ab5/lance_namespace_urllib3_client-0.4.0-py3-none-any.whl", hash = "sha256:858b44b4b34b4ae8f4d905e10a89e4b14f08213dca9dd6751be09cfa03a7dbdc", size = 261516, upload-time = "2025-12-21T16:07:51.946Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.11'", +] +sdist = { url = "https://files.pythonhosted.org/packages/a4/7a/6a3d14e205d292b738db449d0de649b373a59edb0d0b4493821d0a3e8718/numpy-2.4.0.tar.gz", hash = "sha256:6e504f7b16118198f138ef31ba24d985b124c2c469fe8467007cf30fd992f934", size = 20685720, upload-time = "2025-12-20T16:18:19.023Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/7e/7bae7cbcc2f8132271967aa03e03954fc1e48aa1f3bf32b29ca95fbef352/numpy-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:316b2f2584682318539f0bcaca5a496ce9ca78c88066579ebd11fd06f8e4741e", size = 16940166, upload-time = "2025-12-20T16:15:43.434Z" }, + { url = "https://files.pythonhosted.org/packages/0f/27/6c13f5b46776d6246ec884ac5817452672156a506d08a1f2abb39961930a/numpy-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2718c1de8504121714234b6f8241d0019450353276c88b9453c9c3d92e101db", size = 12641781, upload-time = "2025-12-20T16:15:45.701Z" }, + { url = "https://files.pythonhosted.org/packages/14/1c/83b4998d4860d15283241d9e5215f28b40ac31f497c04b12fa7f428ff370/numpy-2.4.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:21555da4ec4a0c942520ead42c3b0dc9477441e085c42b0fbdd6a084869a6f6b", size = 5470247, upload-time = "2025-12-20T16:15:47.943Z" }, + { url = "https://files.pythonhosted.org/packages/54/08/cbce72c835d937795571b0464b52069f869c9e78b0c076d416c5269d2718/numpy-2.4.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:413aa561266a4be2d06cd2b9665e89d9f54c543f418773076a76adcf2af08bc7", size = 6799807, upload-time = "2025-12-20T16:15:49.795Z" }, + { url = "https://files.pythonhosted.org/packages/ff/be/2e647961cd8c980591d75cdcd9e8f647d69fbe05e2a25613dc0a2ea5fb1a/numpy-2.4.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0feafc9e03128074689183031181fac0897ff169692d8492066e949041096548", size = 14701992, upload-time = "2025-12-20T16:15:51.615Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fb/e1652fb8b6fd91ce6ed429143fe2e01ce714711e03e5b762615e7b36172c/numpy-2.4.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8fdfed3deaf1928fb7667d96e0567cdf58c2b370ea2ee7e586aa383ec2cb346", size = 16646871, upload-time = "2025-12-20T16:15:54.129Z" }, + { url = "https://files.pythonhosted.org/packages/62/23/d841207e63c4322842f7cd042ae981cffe715c73376dcad8235fb31debf1/numpy-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e06a922a469cae9a57100864caf4f8a97a1026513793969f8ba5b63137a35d25", size = 16487190, upload-time = "2025-12-20T16:15:56.147Z" }, + { url = "https://files.pythonhosted.org/packages/bc/a0/6a842c8421ebfdec0a230e65f61e0dabda6edbef443d999d79b87c273965/numpy-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:927ccf5cd17c48f801f4ed43a7e5673a2724bd2171460be3e3894e6e332ef83a", size = 18580762, upload-time = "2025-12-20T16:15:58.524Z" }, + { url = "https://files.pythonhosted.org/packages/0a/d1/c79e0046641186f2134dde05e6181825b911f8bdcef31b19ddd16e232847/numpy-2.4.0-cp311-cp311-win32.whl", hash = "sha256:882567b7ae57c1b1a0250208cc21a7976d8cbcc49d5a322e607e6f09c9e0bd53", size = 6233359, upload-time = "2025-12-20T16:16:00.938Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f0/74965001d231f28184d6305b8cdc1b6fcd4bf23033f6cb039cfe76c9fca7/numpy-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b986403023c8f3bf8f487c2e6186afda156174d31c175f747d8934dfddf3479", size = 12601132, upload-time = "2025-12-20T16:16:02.484Z" }, + { url = "https://files.pythonhosted.org/packages/65/32/55408d0f46dfebce38017f5bd931affa7256ad6beac1a92a012e1fbc67a7/numpy-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:3f3096405acc48887458bbf9f6814d43785ac7ba2a57ea6442b581dedbc60ce6", size = 10573977, upload-time = "2025-12-20T16:16:04.77Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ff/f6400ffec95de41c74b8e73df32e3fff1830633193a7b1e409be7fb1bb8c/numpy-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a8b6bb8369abefb8bd1801b054ad50e02b3275c8614dc6e5b0373c305291037", size = 16653117, upload-time = "2025-12-20T16:16:06.709Z" }, + { url = "https://files.pythonhosted.org/packages/fd/28/6c23e97450035072e8d830a3c411bf1abd1f42c611ff9d29e3d8f55c6252/numpy-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e284ca13d5a8367e43734148622caf0b261b275673823593e3e3634a6490f83", size = 12369711, upload-time = "2025-12-20T16:16:08.758Z" }, + { url = "https://files.pythonhosted.org/packages/bc/af/acbef97b630ab1bb45e6a7d01d1452e4251aa88ce680ac36e56c272120ec/numpy-2.4.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:49ff32b09f5aa0cd30a20c2b39db3e669c845589f2b7fc910365210887e39344", size = 5198355, upload-time = "2025-12-20T16:16:10.902Z" }, + { url = "https://files.pythonhosted.org/packages/c1/c8/4e0d436b66b826f2e53330adaa6311f5cac9871a5b5c31ad773b27f25a74/numpy-2.4.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:36cbfb13c152b1c7c184ddac43765db8ad672567e7bafff2cc755a09917ed2e6", size = 6545298, upload-time = "2025-12-20T16:16:12.607Z" }, + { url = "https://files.pythonhosted.org/packages/ef/27/e1f5d144ab54eac34875e79037011d511ac57b21b220063310cb96c80fbc/numpy-2.4.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35ddc8f4914466e6fc954c76527aa91aa763682a4f6d73249ef20b418fe6effb", size = 14398387, upload-time = "2025-12-20T16:16:14.257Z" }, + { url = "https://files.pythonhosted.org/packages/67/64/4cb909dd5ab09a9a5d086eff9586e69e827b88a5585517386879474f4cf7/numpy-2.4.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc578891de1db95b2a35001b695451767b580bb45753717498213c5ff3c41d63", size = 16363091, upload-time = "2025-12-20T16:16:17.32Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9c/8efe24577523ec6809261859737cf117b0eb6fdb655abdfdc81b2e468ce4/numpy-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e81648e0b36e325ab67e46b5400a7a6d4a22b8a7c8e8bbfe20e7db7906bf95", size = 16176394, upload-time = "2025-12-20T16:16:19.524Z" }, + { url = "https://files.pythonhosted.org/packages/61/f0/1687441ece7b47a62e45a1f82015352c240765c707928edd8aef875d5951/numpy-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d57b5046c120561ba8fa8e4030fbb8b822f3063910fa901ffadf16e2b7128ad6", size = 18287378, upload-time = "2025-12-20T16:16:22.866Z" }, + { url = "https://files.pythonhosted.org/packages/d3/6f/f868765d44e6fc466467ed810ba9d8d6db1add7d4a748abfa2a4c99a3194/numpy-2.4.0-cp312-cp312-win32.whl", hash = "sha256:92190db305a6f48734d3982f2c60fa30d6b5ee9bff10f2887b930d7b40119f4c", size = 5955432, upload-time = "2025-12-20T16:16:25.06Z" }, + { url = "https://files.pythonhosted.org/packages/d4/b5/94c1e79fcbab38d1ca15e13777477b2914dd2d559b410f96949d6637b085/numpy-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:680060061adb2d74ce352628cb798cfdec399068aa7f07ba9fb818b2b3305f98", size = 12306201, upload-time = "2025-12-20T16:16:26.979Z" }, + { url = "https://files.pythonhosted.org/packages/70/09/c39dadf0b13bb0768cd29d6a3aaff1fb7c6905ac40e9aaeca26b1c086e06/numpy-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:39699233bc72dd482da1415dcb06076e32f60eddc796a796c5fb6c5efce94667", size = 10308234, upload-time = "2025-12-20T16:16:29.417Z" }, + { url = "https://files.pythonhosted.org/packages/a7/0d/853fd96372eda07c824d24adf02e8bc92bb3731b43a9b2a39161c3667cc4/numpy-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a152d86a3ae00ba5f47b3acf3b827509fd0b6cb7d3259665e63dafbad22a75ea", size = 16649088, upload-time = "2025-12-20T16:16:31.421Z" }, + { url = "https://files.pythonhosted.org/packages/e3/37/cc636f1f2a9f585434e20a3e6e63422f70bfe4f7f6698e941db52ea1ac9a/numpy-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39b19251dec4de8ff8496cd0806cbe27bf0684f765abb1f4809554de93785f2d", size = 12364065, upload-time = "2025-12-20T16:16:33.491Z" }, + { url = "https://files.pythonhosted.org/packages/ed/69/0b78f37ca3690969beee54103ce5f6021709134e8020767e93ba691a72f1/numpy-2.4.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:009bd0ea12d3c784b6639a8457537016ce5172109e585338e11334f6a7bb88ee", size = 5192640, upload-time = "2025-12-20T16:16:35.636Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2a/08569f8252abf590294dbb09a430543ec8f8cc710383abfb3e75cc73aeda/numpy-2.4.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5fe44e277225fd3dff6882d86d3d447205d43532c3627313d17e754fb3905a0e", size = 6541556, upload-time = "2025-12-20T16:16:37.276Z" }, + { url = "https://files.pythonhosted.org/packages/93/e9/a949885a4e177493d61519377952186b6cbfdf1d6002764c664ba28349b5/numpy-2.4.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f935c4493eda9069851058fa0d9e39dbf6286be690066509305e52912714dbb2", size = 14396562, upload-time = "2025-12-20T16:16:38.953Z" }, + { url = "https://files.pythonhosted.org/packages/99/98/9d4ad53b0e9ef901c2ef1d550d2136f5ac42d3fd2988390a6def32e23e48/numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a", size = 16351719, upload-time = "2025-12-20T16:16:41.503Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/5f3711a38341d6e8dd619f6353251a0cdd07f3d6d101a8fd46f4ef87f895/numpy-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba0cb30acd3ef11c94dc27fbfba68940652492bc107075e7ffe23057f9425681", size = 16176053, upload-time = "2025-12-20T16:16:44.552Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5b/2a3753dc43916501b4183532e7ace862e13211042bceafa253afb5c71272/numpy-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60e8c196cd82cbbd4f130b5290007e13e6de3eca79f0d4d38014769d96a7c475", size = 18277859, upload-time = "2025-12-20T16:16:47.174Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c5/a18bcdd07a941db3076ef489d036ab16d2bfc2eae0cf27e5a26e29189434/numpy-2.4.0-cp313-cp313-win32.whl", hash = "sha256:5f48cb3e88fbc294dc90e215d86fbaf1c852c63dbdb6c3a3e63f45c4b57f7344", size = 5953849, upload-time = "2025-12-20T16:16:49.554Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f1/719010ff8061da6e8a26e1980cf090412d4f5f8060b31f0c45d77dd67a01/numpy-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:a899699294f28f7be8992853c0c60741f16ff199205e2e6cdca155762cbaa59d", size = 12302840, upload-time = "2025-12-20T16:16:51.227Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5a/b3d259083ed8b4d335270c76966cb6cf14a5d1b69e1a608994ac57a659e6/numpy-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9198f447e1dc5647d07c9a6bbe2063cc0132728cc7175b39dbc796da5b54920d", size = 10308509, upload-time = "2025-12-20T16:16:53.313Z" }, + { url = "https://files.pythonhosted.org/packages/31/01/95edcffd1bb6c0633df4e808130545c4f07383ab629ac7e316fb44fff677/numpy-2.4.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74623f2ab5cc3f7c886add4f735d1031a1d2be4a4ae63c0546cfd74e7a31ddf6", size = 12491815, upload-time = "2025-12-20T16:16:55.496Z" }, + { url = "https://files.pythonhosted.org/packages/59/ea/5644b8baa92cc1c7163b4b4458c8679852733fa74ca49c942cfa82ded4e0/numpy-2.4.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0804a8e4ab070d1d35496e65ffd3cf8114c136a2b81f61dfab0de4b218aacfd5", size = 5320321, upload-time = "2025-12-20T16:16:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/26/4e/e10938106d70bc21319bd6a86ae726da37edc802ce35a3a71ecdf1fdfe7f/numpy-2.4.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:02a2038eb27f9443a8b266a66911e926566b5a6ffd1a689b588f7f35b81e7dc3", size = 6641635, upload-time = "2025-12-20T16:16:59.379Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8d/a8828e3eaf5c0b4ab116924df82f24ce3416fa38d0674d8f708ddc6c8aac/numpy-2.4.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1889b3a3f47a7b5bee16bc25a2145bd7cb91897f815ce3499db64c7458b6d91d", size = 14456053, upload-time = "2025-12-20T16:17:01.768Z" }, + { url = "https://files.pythonhosted.org/packages/68/a1/17d97609d87d4520aa5ae2dcfb32305654550ac6a35effb946d303e594ce/numpy-2.4.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85eef4cb5625c47ee6425c58a3502555e10f45ee973da878ac8248ad58c136f3", size = 16401702, upload-time = "2025-12-20T16:17:04.235Z" }, + { url = "https://files.pythonhosted.org/packages/18/32/0f13c1b2d22bea1118356b8b963195446f3af124ed7a5adfa8fdecb1b6ca/numpy-2.4.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6dc8b7e2f4eb184b37655195f421836cfae6f58197b67e3ffc501f1333d993fa", size = 16242493, upload-time = "2025-12-20T16:17:06.856Z" }, + { url = "https://files.pythonhosted.org/packages/ae/23/48f21e3d309fbc137c068a1475358cbd3a901b3987dcfc97a029ab3068e2/numpy-2.4.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:44aba2f0cafd287871a495fb3163408b0bd25bbce135c6f621534a07f4f7875c", size = 18324222, upload-time = "2025-12-20T16:17:09.392Z" }, + { url = "https://files.pythonhosted.org/packages/ac/52/41f3d71296a3dcaa4f456aaa3c6fc8e745b43d0552b6bde56571bb4b4a0f/numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93", size = 6076216, upload-time = "2025-12-20T16:17:11.437Z" }, + { url = "https://files.pythonhosted.org/packages/35/ff/46fbfe60ab0710d2a2b16995f708750307d30eccbb4c38371ea9e986866e/numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4", size = 12444263, upload-time = "2025-12-20T16:17:13.182Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e3/9189ab319c01d2ed556c932ccf55064c5d75bb5850d1df7a482ce0badead/numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c", size = 10378265, upload-time = "2025-12-20T16:17:15.211Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ed/52eac27de39d5e5a6c9aadabe672bc06f55e24a3d9010cd1183948055d76/numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b", size = 16647476, upload-time = "2025-12-20T16:17:17.671Z" }, + { url = "https://files.pythonhosted.org/packages/77/c0/990ce1b7fcd4e09aeaa574e2a0a839589e4b08b2ca68070f1acb1fea6736/numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e", size = 12374563, upload-time = "2025-12-20T16:17:20.216Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/8c5e389c6ae8f5fd2277a988600d79e9625db3fff011a2d87ac80b881a4c/numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e", size = 5203107, upload-time = "2025-12-20T16:17:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/e6/94/ca5b3bd6a8a70a5eec9a0b8dd7f980c1eff4b8a54970a9a7fef248ef564f/numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51", size = 6538067, upload-time = "2025-12-20T16:17:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/79/43/993eb7bb5be6761dde2b3a3a594d689cec83398e3f58f4758010f3b85727/numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce", size = 14411926, upload-time = "2025-12-20T16:17:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/03/75/d4c43b61de473912496317a854dac54f1efec3eeb158438da6884b70bb90/numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f", size = 16354295, upload-time = "2025-12-20T16:17:28.308Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0a/b54615b47ee8736a6461a4bb6749128dd3435c5a759d5663f11f0e9af4ac/numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded", size = 16190242, upload-time = "2025-12-20T16:17:30.993Z" }, + { url = "https://files.pythonhosted.org/packages/98/ce/ea207769aacad6246525ec6c6bbd66a2bf56c72443dc10e2f90feed29290/numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059", size = 18280875, upload-time = "2025-12-20T16:17:33.327Z" }, + { url = "https://files.pythonhosted.org/packages/17/ef/ec409437aa962ea372ed601c519a2b141701683ff028f894b7466f0ab42b/numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db", size = 6002530, upload-time = "2025-12-20T16:17:35.729Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4a/5cb94c787a3ed1ac65e1271b968686521169a7b3ec0b6544bb3ca32960b0/numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e", size = 12435890, upload-time = "2025-12-20T16:17:37.599Z" }, + { url = "https://files.pythonhosted.org/packages/48/a0/04b89db963af9de1104975e2544f30de89adbf75b9e75f7dd2599be12c79/numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63", size = 10591892, upload-time = "2025-12-20T16:17:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/53/e5/d74b5ccf6712c06c7a545025a6a71bfa03bdc7e0568b405b0d655232fd92/numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df", size = 12494312, upload-time = "2025-12-20T16:17:41.714Z" }, + { url = "https://files.pythonhosted.org/packages/c2/08/3ca9cc2ddf54dfee7ae9a6479c071092a228c68aef08252aa08dac2af002/numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9", size = 5322862, upload-time = "2025-12-20T16:17:44.145Z" }, + { url = "https://files.pythonhosted.org/packages/87/74/0bb63a68394c0c1e52670cfff2e309afa41edbe11b3327d9af29e4383f34/numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9", size = 6644986, upload-time = "2025-12-20T16:17:46.203Z" }, + { url = "https://files.pythonhosted.org/packages/06/8f/9264d9bdbcf8236af2823623fe2f3981d740fc3461e2787e231d97c38c28/numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471", size = 14457958, upload-time = "2025-12-20T16:17:48.017Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d9/f9a69ae564bbc7236a35aa883319364ef5fd41f72aa320cc1cbe66148fe2/numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544", size = 16398394, upload-time = "2025-12-20T16:17:50.409Z" }, + { url = "https://files.pythonhosted.org/packages/34/c7/39241501408dde7f885d241a98caba5421061a2c6d2b2197ac5e3aa842d8/numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c", size = 16241044, upload-time = "2025-12-20T16:17:52.661Z" }, + { url = "https://files.pythonhosted.org/packages/7c/95/cae7effd90e065a95e59fe710eeee05d7328ed169776dfdd9f789e032125/numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac", size = 18321772, upload-time = "2025-12-20T16:17:54.947Z" }, + { url = "https://files.pythonhosted.org/packages/96/df/3c6c279accd2bfb968a76298e5b276310bd55d243df4fa8ac5816d79347d/numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f", size = 6148320, upload-time = "2025-12-20T16:17:57.249Z" }, + { url = "https://files.pythonhosted.org/packages/92/8d/f23033cce252e7a75cae853d17f582e86534c46404dea1c8ee094a9d6d84/numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4", size = 12623460, upload-time = "2025-12-20T16:17:58.963Z" }, + { url = "https://files.pythonhosted.org/packages/a4/4f/1f8475907d1a7c4ef9020edf7f39ea2422ec896849245f00688e4b268a71/numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8", size = 10661799, upload-time = "2025-12-20T16:18:01.078Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ef/088e7c7342f300aaf3ee5f2c821c4b9996a1bef2aaf6a49cc8ab4883758e/numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6", size = 16819003, upload-time = "2025-12-20T16:18:03.41Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ce/a53017b5443b4b84517182d463fc7bcc2adb4faa8b20813f8e5f5aeb5faa/numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4", size = 12567105, upload-time = "2025-12-20T16:18:05.594Z" }, + { url = "https://files.pythonhosted.org/packages/77/58/5ff91b161f2ec650c88a626c3905d938c89aaadabd0431e6d9c1330c83e2/numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba", size = 5395590, upload-time = "2025-12-20T16:18:08.031Z" }, + { url = "https://files.pythonhosted.org/packages/1d/4e/f1a084106df8c2df8132fc437e56987308e0524836aa7733721c8429d4fe/numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2f585f52b2baf07ff3356158d9268ea095e221371f1074fadea2f42544d58b4d", size = 6709947, upload-time = "2025-12-20T16:18:09.836Z" }, + { url = "https://files.pythonhosted.org/packages/63/09/3d8aeb809c0332c3f642da812ac2e3d74fc9252b3021f8c30c82e99e3f3d/numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32ed06d0fe9cae27d8fb5f400c63ccee72370599c75e683a6358dd3a4fb50aaf", size = 14535119, upload-time = "2025-12-20T16:18:12.105Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7f/68f0fc43a2cbdc6bb239160c754d87c922f60fbaa0fa3cd3d312b8a7f5ee/numpy-2.4.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57c540ed8fb1f05cb997c6761cd56db72395b0d6985e90571ff660452ade4f98", size = 16475815, upload-time = "2025-12-20T16:18:14.433Z" }, + { url = "https://files.pythonhosted.org/packages/11/73/edeacba3167b1ca66d51b1a5a14697c2c40098b5ffa01811c67b1785a5ab/numpy-2.4.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:a39fb973a726e63223287adc6dafe444ce75af952d711e400f3bf2b36ef55a7b", size = 12489376, upload-time = "2025-12-20T16:18:16.524Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pyarrow" +version = "22.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/53/04a7fdc63e6056116c9ddc8b43bc28c12cdd181b85cbeadb79278475f3ae/pyarrow-22.0.0.tar.gz", hash = "sha256:3d600dc583260d845c7d8a6db540339dd883081925da2bd1c5cb808f720b3cd9", size = 1151151, upload-time = "2025-10-24T12:30:00.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/9b/cb3f7e0a345353def531ca879053e9ef6b9f38ed91aebcf68b09ba54dec0/pyarrow-22.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:77718810bd3066158db1e95a63c160ad7ce08c6b0710bc656055033e39cdad88", size = 34223968, upload-time = "2025-10-24T10:03:31.21Z" }, + { url = "https://files.pythonhosted.org/packages/6c/41/3184b8192a120306270c5307f105b70320fdaa592c99843c5ef78aaefdcf/pyarrow-22.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:44d2d26cda26d18f7af7db71453b7b783788322d756e81730acb98f24eb90ace", size = 35942085, upload-time = "2025-10-24T10:03:38.146Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3d/a1eab2f6f08001f9fb714b8ed5cfb045e2fe3e3e3c0c221f2c9ed1e6d67d/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b9d71701ce97c95480fecb0039ec5bb889e75f110da72005743451339262f4ce", size = 44964613, upload-time = "2025-10-24T10:03:46.516Z" }, + { url = "https://files.pythonhosted.org/packages/46/46/a1d9c24baf21cfd9ce994ac820a24608decf2710521b29223d4334985127/pyarrow-22.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:710624ab925dc2b05a6229d47f6f0dac1c1155e6ed559be7109f684eba048a48", size = 47627059, upload-time = "2025-10-24T10:03:55.353Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4c/f711acb13075c1391fd54bc17e078587672c575f8de2a6e62509af026dcf/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f963ba8c3b0199f9d6b794c90ec77545e05eadc83973897a4523c9e8d84e9340", size = 47947043, upload-time = "2025-10-24T10:04:05.408Z" }, + { url = "https://files.pythonhosted.org/packages/4e/70/1f3180dd7c2eab35c2aca2b29ace6c519f827dcd4cfeb8e0dca41612cf7a/pyarrow-22.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd0d42297ace400d8febe55f13fdf46e86754842b860c978dfec16f081e5c653", size = 50206505, upload-time = "2025-10-24T10:04:15.786Z" }, + { url = "https://files.pythonhosted.org/packages/80/07/fea6578112c8c60ffde55883a571e4c4c6bc7049f119d6b09333b5cc6f73/pyarrow-22.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:00626d9dc0f5ef3a75fe63fd68b9c7c8302d2b5bbc7f74ecaedba83447a24f84", size = 28101641, upload-time = "2025-10-24T10:04:22.57Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b7/18f611a8cdc43417f9394a3ccd3eace2f32183c08b9eddc3d17681819f37/pyarrow-22.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:3e294c5eadfb93d78b0763e859a0c16d4051fc1c5231ae8956d61cb0b5666f5a", size = 34272022, upload-time = "2025-10-24T10:04:28.973Z" }, + { url = "https://files.pythonhosted.org/packages/26/5c/f259e2526c67eb4b9e511741b19870a02363a47a35edbebc55c3178db22d/pyarrow-22.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:69763ab2445f632d90b504a815a2a033f74332997052b721002298ed6de40f2e", size = 35995834, upload-time = "2025-10-24T10:04:35.467Z" }, + { url = "https://files.pythonhosted.org/packages/50/8d/281f0f9b9376d4b7f146913b26fac0aa2829cd1ee7e997f53a27411bbb92/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:b41f37cabfe2463232684de44bad753d6be08a7a072f6a83447eeaf0e4d2a215", size = 45030348, upload-time = "2025-10-24T10:04:43.366Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e5/53c0a1c428f0976bf22f513d79c73000926cb00b9c138d8e02daf2102e18/pyarrow-22.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:35ad0f0378c9359b3f297299c3309778bb03b8612f987399a0333a560b43862d", size = 47699480, upload-time = "2025-10-24T10:04:51.486Z" }, + { url = "https://files.pythonhosted.org/packages/95/e1/9dbe4c465c3365959d183e6345d0a8d1dc5b02ca3f8db4760b3bc834cf25/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8382ad21458075c2e66a82a29d650f963ce51c7708c7c0ff313a8c206c4fd5e8", size = 48011148, upload-time = "2025-10-24T10:04:59.585Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b4/7caf5d21930061444c3cf4fa7535c82faf5263e22ce43af7c2759ceb5b8b/pyarrow-22.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a812a5b727bc09c3d7ea072c4eebf657c2f7066155506ba31ebf4792f88f016", size = 50276964, upload-time = "2025-10-24T10:05:08.175Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f3/cec89bd99fa3abf826f14d4e53d3d11340ce6f6af4d14bdcd54cd83b6576/pyarrow-22.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ec5d40dd494882704fb876c16fa7261a69791e784ae34e6b5992e977bd2e238c", size = 28106517, upload-time = "2025-10-24T10:05:14.314Z" }, + { url = "https://files.pythonhosted.org/packages/af/63/ba23862d69652f85b615ca14ad14f3bcfc5bf1b99ef3f0cd04ff93fdad5a/pyarrow-22.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bea79263d55c24a32b0d79c00a1c58bb2ee5f0757ed95656b01c0fb310c5af3d", size = 34211578, upload-time = "2025-10-24T10:05:21.583Z" }, + { url = "https://files.pythonhosted.org/packages/b1/d0/f9ad86fe809efd2bcc8be32032fa72e8b0d112b01ae56a053006376c5930/pyarrow-22.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:12fe549c9b10ac98c91cf791d2945e878875d95508e1a5d14091a7aaa66d9cf8", size = 35989906, upload-time = "2025-10-24T10:05:29.485Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a8/f910afcb14630e64d673f15904ec27dd31f1e009b77033c365c84e8c1e1d/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:334f900ff08ce0423407af97e6c26ad5d4e3b0763645559ece6fbf3747d6a8f5", size = 45021677, upload-time = "2025-10-24T10:05:38.274Z" }, + { url = "https://files.pythonhosted.org/packages/13/95/aec81f781c75cd10554dc17a25849c720d54feafb6f7847690478dcf5ef8/pyarrow-22.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c6c791b09c57ed76a18b03f2631753a4960eefbbca80f846da8baefc6491fcfe", size = 47726315, upload-time = "2025-10-24T10:05:47.314Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d4/74ac9f7a54cfde12ee42734ea25d5a3c9a45db78f9def949307a92720d37/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c3200cb41cdbc65156e5f8c908d739b0dfed57e890329413da2748d1a2cd1a4e", size = 47990906, upload-time = "2025-10-24T10:05:58.254Z" }, + { url = "https://files.pythonhosted.org/packages/2e/71/fedf2499bf7a95062eafc989ace56572f3343432570e1c54e6599d5b88da/pyarrow-22.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ac93252226cf288753d8b46280f4edf3433bf9508b6977f8dd8526b521a1bbb9", size = 50306783, upload-time = "2025-10-24T10:06:08.08Z" }, + { url = "https://files.pythonhosted.org/packages/68/ed/b202abd5a5b78f519722f3d29063dda03c114711093c1995a33b8e2e0f4b/pyarrow-22.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:44729980b6c50a5f2bfcc2668d36c569ce17f8b17bccaf470c4313dcbbf13c9d", size = 27972883, upload-time = "2025-10-24T10:06:14.204Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d6/d0fac16a2963002fc22c8fa75180a838737203d558f0ed3b564c4a54eef5/pyarrow-22.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e6e95176209257803a8b3d0394f21604e796dadb643d2f7ca21b66c9c0b30c9a", size = 34204629, upload-time = "2025-10-24T10:06:20.274Z" }, + { url = "https://files.pythonhosted.org/packages/c6/9c/1d6357347fbae062ad3f17082f9ebc29cc733321e892c0d2085f42a2212b/pyarrow-22.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:001ea83a58024818826a9e3f89bf9310a114f7e26dfe404a4c32686f97bd7901", size = 35985783, upload-time = "2025-10-24T10:06:27.301Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c0/782344c2ce58afbea010150df07e3a2f5fdad299cd631697ae7bd3bac6e3/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:ce20fe000754f477c8a9125543f1936ea5b8867c5406757c224d745ed033e691", size = 45020999, upload-time = "2025-10-24T10:06:35.387Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8b/5362443737a5307a7b67c1017c42cd104213189b4970bf607e05faf9c525/pyarrow-22.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e0a15757fccb38c410947df156f9749ae4a3c89b2393741a50521f39a8cf202a", size = 47724601, upload-time = "2025-10-24T10:06:43.551Z" }, + { url = "https://files.pythonhosted.org/packages/69/4d/76e567a4fc2e190ee6072967cb4672b7d9249ac59ae65af2d7e3047afa3b/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cedb9dd9358e4ea1d9bce3665ce0797f6adf97ff142c8e25b46ba9cdd508e9b6", size = 48001050, upload-time = "2025-10-24T10:06:52.284Z" }, + { url = "https://files.pythonhosted.org/packages/01/5e/5653f0535d2a1aef8223cee9d92944cb6bccfee5cf1cd3f462d7cb022790/pyarrow-22.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:252be4a05f9d9185bb8c18e83764ebcfea7185076c07a7a662253af3a8c07941", size = 50307877, upload-time = "2025-10-24T10:07:02.405Z" }, + { url = "https://files.pythonhosted.org/packages/2d/f8/1d0bd75bf9328a3b826e24a16e5517cd7f9fbf8d34a3184a4566ef5a7f29/pyarrow-22.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:a4893d31e5ef780b6edcaf63122df0f8d321088bb0dee4c8c06eccb1ca28d145", size = 27977099, upload-time = "2025-10-24T10:08:07.259Z" }, + { url = "https://files.pythonhosted.org/packages/90/81/db56870c997805bf2b0f6eeeb2d68458bf4654652dccdcf1bf7a42d80903/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:f7fe3dbe871294ba70d789be16b6e7e52b418311e166e0e3cba9522f0f437fb1", size = 34336685, upload-time = "2025-10-24T10:07:11.47Z" }, + { url = "https://files.pythonhosted.org/packages/1c/98/0727947f199aba8a120f47dfc229eeb05df15bcd7a6f1b669e9f882afc58/pyarrow-22.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:ba95112d15fd4f1105fb2402c4eab9068f0554435e9b7085924bcfaac2cc306f", size = 36032158, upload-time = "2025-10-24T10:07:18.626Z" }, + { url = "https://files.pythonhosted.org/packages/96/b4/9babdef9c01720a0785945c7cf550e4acd0ebcd7bdd2e6f0aa7981fa85e2/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:c064e28361c05d72eed8e744c9605cbd6d2bb7481a511c74071fd9b24bc65d7d", size = 44892060, upload-time = "2025-10-24T10:07:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ca/2f8804edd6279f78a37062d813de3f16f29183874447ef6d1aadbb4efa0f/pyarrow-22.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6f9762274496c244d951c819348afbcf212714902742225f649cf02823a6a10f", size = 47504395, upload-time = "2025-10-24T10:07:34.09Z" }, + { url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" }, + { url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" }, + { url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" }, + { url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload-time = "2025-10-24T10:08:14.101Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload-time = "2025-10-24T10:08:21.842Z" }, + { url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload-time = "2025-10-24T10:08:29.034Z" }, + { url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload-time = "2025-10-24T10:08:38.559Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload-time = "2025-10-24T10:08:46.784Z" }, + { url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload-time = "2025-10-24T10:08:55.771Z" }, + { url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload-time = "2025-10-24T10:09:59.891Z" }, + { url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload-time = "2025-10-24T10:09:02.953Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload-time = "2025-10-24T10:09:10.334Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload-time = "2025-10-24T10:09:18.61Z" }, + { url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload-time = "2025-10-24T10:09:27.369Z" }, + { url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload-time = "2025-10-24T10:09:34.908Z" }, + { url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload-time = "2025-10-24T10:09:44.394Z" }, + { url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload-time = "2025-11-04T13:39:04.116Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload-time = "2025-11-04T13:39:06.055Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload-time = "2025-11-04T13:39:10.41Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload-time = "2025-11-04T13:39:12.244Z" }, + { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload-time = "2025-11-04T13:39:13.962Z" }, + { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload-time = "2025-11-04T13:39:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload-time = "2025-11-04T13:39:17.403Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload-time = "2025-11-04T13:39:19.351Z" }, + { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload-time = "2025-11-04T13:39:21Z" }, + { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload-time = "2025-11-04T13:39:22.606Z" }, + { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload-time = "2025-11-04T13:39:25.843Z" }, + { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload-time = "2025-11-04T13:39:27.92Z" }, + { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload-time = "2025-11-04T13:39:29.848Z" }, + { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, + { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, + { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, + { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, + { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, + { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, + { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, + { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, + { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, + { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, + { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, + { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, + { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, + { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, + { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, + { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, + { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, + { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, + { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, + { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, + { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, + { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, + { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, + { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, + { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, + { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload-time = "2025-11-04T13:43:02.058Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload-time = "2025-11-04T13:43:05.159Z" }, + { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload-time = "2025-11-04T13:43:08.116Z" }, + { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload-time = "2025-11-04T13:43:12.49Z" }, + { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload-time = "2025-11-04T13:43:15.431Z" }, + { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload-time = "2025-11-04T13:43:18.062Z" }, + { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload-time = "2025-11-04T13:43:20.679Z" }, + { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload-time = "2025-11-04T13:43:23.286Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, + { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, + { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, + { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, + { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pylance" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lance-namespace" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "numpy", version = "2.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pyarrow" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/5c/501e3a5d73b8ef1247045ce959fa6f8932753eacf192b7a122f394a063a0/pylance-1.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:f1d70a59868dcee62862545f9f0846b328ee013f845bec536ff6d8aac23e3bfb", size = 49829642, upload-time = "2025-12-12T21:42:52.81Z" }, + { url = "https://files.pythonhosted.org/packages/22/74/a30ad89ce6bf818c9551224ce0d2bfe4f67d7d99b3f8298f8860b12e3de6/pylance-1.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29f2af7d4eed932334b98c991b1d0c105de89a706f95ae40cce48385c6f5589e", size = 52193853, upload-time = "2025-12-12T21:51:49.609Z" }, + { url = "https://files.pythonhosted.org/packages/e8/4d/160ca42beb5e903dd1dc6526fb8b0b3a0fe4750e9f04d3f16531ef23b158/pylance-1.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05196823a7698571c122f861038193a591fe55d42a0532c1183756a9f1602cf3", size = 55557899, upload-time = "2025-12-12T21:58:02.104Z" }, + { url = "https://files.pythonhosted.org/packages/a8/4e/6fd71a0e0ba8560061d3222773c9d9406beb4d9f12dc8dcdce36964d6884/pylance-1.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:78db3a4270f0171870cfbfc13abe6af16e50565f111a8fe57b551600cfa27566", size = 52217155, upload-time = "2025-12-12T21:51:13.615Z" }, + { url = "https://files.pythonhosted.org/packages/cc/a5/5c3c0605fb93d38d889e4219a8987e46863ab42e4ac46b8922afea0a5263/pylance-1.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4564edbe124052272c802bfc7d43de9a7448fe8ee25d10376dcfeed2f3c42ff8", size = 55530328, upload-time = "2025-12-12T21:58:36.733Z" }, + { url = "https://files.pythonhosted.org/packages/f5/05/2fd1188e0ccb419e45e30788c033ff6fd98fc3b8ccc204ef7c67bcc82146/pylance-1.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:cfc3e03709e64f255fc5c9dd9ac8847d8c24cce971cf290cffe92068b320188d", size = 59355812, upload-time = "2025-12-12T22:18:08.83Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "s3transfer" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "botocore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/04/74127fc843314818edfa81b5540e26dd537353b123a4edc563109d8f17dd/s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920", size = 153827, upload-time = "2025-12-01T02:30:59.114Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/51/727abb13f44c1fcf6d145979e1535a35794db0f6e450a0cb46aa24732fe2/s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe", size = 86830, upload-time = "2025-12-01T02:30:57.729Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "thrift" +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/1e/3284d19d7be99305eda145b8aa46b0c33244e4a496ec66440dac19f8274d/thrift-0.13.0.tar.gz", hash = "sha256:9af1c86bf73433afc6010ed376a6c6aca2b54099cc0d61895f640870a9ae7d89", size = 59911, upload-time = "2019-11-18T04:50:57.646Z" } + +[[package]] +name = "tomli" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" }, + { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" }, + { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" }, + { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" }, + { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" }, + { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" }, + { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" }, + { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" }, + { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" }, + { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" }, + { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" }, + { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" }, + { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" }, + { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" }, + { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" }, + { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" }, + { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" }, + { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" }, + { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" }, + { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" }, + { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" }, + { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] From 2149e7eaf740627313a38d77dd9cf1d97541c206 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 17:47:57 -0800 Subject: [PATCH 03/20] fix polaris --- .github/workflows/python-integ-polaris.yml | 46 ++-- docker/polaris/docker-compose.yml | 45 +++- docker/polaris/init-catalog.sh | 67 +++++ docs/src/polaris.md | 71 +++--- java/Makefile | 2 +- .../namespace/polaris/PolarisModels.java | 35 +-- .../namespace/polaris/PolarisNamespace.java | 127 +++++++--- .../polaris/PolarisNamespaceConfig.java | 4 +- .../polaris/TestPolarisNamespace.java | 44 ++-- .../TestPolarisNamespaceIntegration.java | 12 +- python/Makefile | 6 +- python/pyproject.toml | 5 + python/src/lance_namespace_impls/polaris.py | 130 ++++++---- python/tests/test_polaris.py | 119 +++++---- python/tests/test_polaris_integration.py | 228 ++++++++++++++++++ python/uv.lock | 2 +- 16 files changed, 691 insertions(+), 252 deletions(-) create mode 100644 docker/polaris/init-catalog.sh create mode 100644 python/tests/test_polaris_integration.py diff --git a/.github/workflows/python-integ-polaris.yml b/.github/workflows/python-integ-polaris.yml index 7766b31..de80e89 100644 --- a/.github/workflows/python-integ-polaris.yml +++ b/.github/workflows/python-integ-polaris.yml @@ -18,7 +18,9 @@ on: - main paths: - python/src/lance_namespace_impls/polaris.py + - python/src/lance_namespace_impls/rest_client.py - python/tests/test_polaris.py + - python/tests/test_polaris_integration.py - docker/polaris/** - .github/workflows/python-integ-polaris.yml pull_request: @@ -29,7 +31,9 @@ on: - reopened paths: - python/src/lance_namespace_impls/polaris.py + - python/src/lance_namespace_impls/rest_client.py - python/tests/test_polaris.py + - python/tests/test_polaris_integration.py - docker/polaris/** - .github/workflows/python-integ-polaris.yml workflow_dispatch: @@ -53,7 +57,7 @@ jobs: uses: astral-sh/setup-uv@v4 - name: Start Polaris run: make docker-up-polaris - - name: Wait for Polaris to be ready + - name: Wait for Polaris and catalog setup run: | echo "Waiting for Polaris to be ready..." timeout 180 bash -c ' @@ -67,30 +71,32 @@ jobs: exit 1 } echo "Polaris is ready" - - name: Create test catalog - run: | + + # Wait for polaris-setup to complete (creates test_catalog) + echo "Waiting for polaris-setup to complete..." + timeout 60 bash -c ' + while docker ps -q -f name=polaris-setup 2>/dev/null | grep -q .; do + echo "Waiting for polaris-setup container to finish..." + sleep 2 + done + ' || echo "polaris-setup may have already completed" + + # Verify catalog exists + echo "Verifying test_catalog exists..." TOKEN=$(curl -s -X POST http://localhost:8181/api/catalog/v1/oauth/tokens \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=client_credentials&client_id=root&client_secret=s3cr3t&scope=PRINCIPAL_ROLE:ALL' | \ python3 -c "import sys, json; print(json.load(sys.stdin).get('access_token', ''))") - if [ -z "$TOKEN" ]; then - echo "Failed to get OAuth token" - exit 1 + + CATALOGS=$(curl -s http://localhost:8181/api/management/v1/catalogs \ + -H "Authorization: Bearer $TOKEN") + + if echo "$CATALOGS" | grep -q "test_catalog"; then + echo "test_catalog verified" + else + echo "Warning: test_catalog not found in catalogs: $CATALOGS" + docker compose -f docker/polaris/docker-compose.yml logs polaris-setup fi - curl -s -X POST http://localhost:8181/api/catalog/v1/catalogs \ - -H "Authorization: Bearer $TOKEN" \ - -H 'Content-Type: application/json' \ - -d '{ - "name": "test_catalog", - "type": "INTERNAL", - "properties": { - "default-base-location": "file:///data/warehouse/test_catalog" - }, - "storageConfigInfo": { - "storageType": "FILE" - } - }' || echo "Catalog may already exist" - echo "Test catalog created/verified" - name: Install dependencies working-directory: python run: make install-polaris diff --git a/docker/polaris/docker-compose.yml b/docker/polaris/docker-compose.yml index 9f1bec0..796c2c6 100644 --- a/docker/polaris/docker-compose.yml +++ b/docker/polaris/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: postgres-polaris: image: postgres:16 @@ -20,24 +18,37 @@ services: networks: - polaris-network - polaris: - image: apache/polaris:latest - container_name: polaris + polaris-bootstrap: + image: apache/polaris-admin-tool:1.2.0-incubating + container_name: polaris-bootstrap depends_on: postgres-polaris: condition: service_healthy environment: - # Bootstrap credentials: realm,client_id,client_secret + POLARIS_PERSISTENCE_TYPE: relational-jdbc + QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres-polaris:5432/polaris + QUARKUS_DATASOURCE_USERNAME: polaris + QUARKUS_DATASOURCE_PASSWORD: polaris + command: ["bootstrap", "-r", "POLARIS", "-c", "POLARIS,root,s3cr3t"] + networks: + - polaris-network + + polaris: + image: apache/polaris:1.2.0-incubating + container_name: polaris + depends_on: + polaris-bootstrap: + condition: service_completed_successfully + environment: POLARIS_BOOTSTRAP_CREDENTIALS: "POLARIS,root,s3cr3t" - # Persistence configuration POLARIS_PERSISTENCE_TYPE: relational-jdbc QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres-polaris:5432/polaris QUARKUS_DATASOURCE_USERNAME: polaris QUARKUS_DATASOURCE_PASSWORD: polaris - # Allow file:// storage for local testing - POLARIS_FEATURES_DEFAULTS_OVERRIDE_ALLOW_INSECURE_STORAGE_TYPES: "true" - POLARIS_FEATURES_DEFAULTS_OVERRIDE_SUPPORTED_CATALOG_STORAGE_TYPES: '["FILE","S3","GCS","AZURE"]' - # Disable OpenTelemetry for testing + polaris.features."ALLOW_INSECURE_STORAGE_TYPES": "true" + polaris.features."SUPPORTED_CATALOG_STORAGE_TYPES": '["FILE","S3","GCS","AZURE"]' + polaris.features."GENERIC_TABLE_ENABLED": "true" + polaris.readiness.ignore-severe-issues: "true" QUARKUS_OTEL_SDK_DISABLED: "true" ports: - "8181:8181" @@ -53,6 +64,18 @@ services: retries: 10 start_period: 30s + polaris-setup: + image: alpine:3.20 + container_name: polaris-setup + depends_on: + polaris: + condition: service_healthy + volumes: + - ./init-catalog.sh:/init-catalog.sh:ro + command: ["/bin/sh", "/init-catalog.sh"] + networks: + - polaris-network + volumes: polaris-postgres-data: polaris-warehouse: diff --git a/docker/polaris/init-catalog.sh b/docker/polaris/init-catalog.sh new file mode 100644 index 0000000..f1fe22c --- /dev/null +++ b/docker/polaris/init-catalog.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# Wait for Polaris to be healthy +echo "Waiting for Polaris to be ready..." +until wget -q -O /dev/null http://polaris:8182/q/health 2>/dev/null; do + echo "Polaris not ready, waiting..." + sleep 2 +done +echo "Polaris is healthy!" + +# Get OAuth token +echo "Getting OAuth token..." +TOKEN_RESPONSE=$(wget -q -O - --post-data='grant_type=client_credentials&client_id=root&client_secret=s3cr3t&scope=PRINCIPAL_ROLE:ALL' \ + --header='Content-Type: application/x-www-form-urlencoded' \ + http://polaris:8181/api/catalog/v1/oauth/tokens) + +TOKEN=$(echo "$TOKEN_RESPONSE" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p') + +if [ -z "$TOKEN" ]; then + echo "Failed to get OAuth token" + echo "Response: $TOKEN_RESPONSE" + exit 1 +fi +echo "Token obtained successfully" + +# Check if catalog already exists +echo "Checking for existing catalog..." +CATALOGS=$(wget -q -O - --header="Authorization: Bearer $TOKEN" \ + http://polaris:8181/api/management/v1/catalogs) + +if echo "$CATALOGS" | grep -q '"name":"test_catalog"'; then + echo "Catalog 'test_catalog' already exists" + exit 0 +fi + +# Create test catalog +echo "Creating test catalog..." +RESULT=$(wget -q -O - --post-data='{ + "catalog": { + "name": "test_catalog", + "type": "INTERNAL", + "properties": { + "default-base-location": "file:///data/warehouse/test_catalog" + }, + "storageConfigInfo": { + "storageType": "FILE", + "allowedLocations": ["file:///data/warehouse"] + } + } +}' \ + --header="Authorization: Bearer $TOKEN" \ + --header='Content-Type: application/json' \ + http://polaris:8181/api/management/v1/catalogs 2>&1) + +echo "Result: $RESULT" + +# Verify catalog was created +VERIFY=$(wget -q -O - --header="Authorization: Bearer $TOKEN" \ + http://polaris:8181/api/management/v1/catalogs) + +if echo "$VERIFY" | grep -q '"name":"test_catalog"'; then + echo "Catalog 'test_catalog' created successfully!" + exit 0 +else + echo "Failed to create catalog" + echo "Catalogs: $VERIFY" + exit 1 +fi diff --git a/docs/src/polaris.md b/docs/src/polaris.md index 68843ae..77cd883 100644 --- a/docs/src/polaris.md +++ b/docs/src/polaris.md @@ -6,6 +6,8 @@ This document describes how the Polaris Catalog implements the Lance Namespace c Apache Polaris is an open-source catalog implementation for Apache Iceberg that provides a REST API for managing tables and namespaces. Polaris supports the Generic Table API which allows registering non-Iceberg table formats. For details on Polaris Catalog, see the [Polaris Catalog Documentation](https://polaris.apache.org). +**Note:** The Generic Table API is available in Polaris 1.2.0-incubating and later versions. Ensure your Polaris deployment is running a compatible version. + ## Namespace Implementation Configuration Properties The Lance Polaris namespace implementation accepts the following configuration properties: @@ -24,11 +26,14 @@ The **max_retries** property is optional and specifies the maximum number of ret ### Namespace -The **root namespace** is represented by the Polaris catalog root, accessed via the `/namespaces` endpoint. +The **namespace identifier** follows a hierarchical structure where the first level represents the Polaris catalog (warehouse), and subsequent levels represent namespaces within that catalog. For example, `my_catalog.my_schema` refers to namespace `my_schema` in catalog `my_catalog`. -A **child namespace** is a nested namespace in Polaris. Polaris supports arbitrary nesting depth, allowing flexible namespace organization. First-level namespaces typically represent catalogs, with subsequent levels representing schemas or other organizational units. +A **child namespace** is a nested namespace in Polaris. Polaris supports arbitrary nesting depth, allowing flexible namespace organization within a catalog. -The **namespace identifier** is constructed by joining namespace levels with the `.` delimiter (e.g., `catalog.schema`). When making API calls, the namespace path is URL-encoded. +The **namespace identifier** is constructed by joining the catalog and namespace levels with the `.` delimiter (e.g., `catalog.schema.subschema`). When making API calls: +- The catalog is extracted as the first level +- Remaining levels form the namespace path within that catalog +- The namespace path is URL-encoded using `.` as the separator **Namespace properties** are stored in the namespace's properties map, returned by the Polaris namespace API. @@ -54,10 +59,11 @@ Creates a new namespace in Polaris. The implementation: -1. Parse the namespace identifier to get the namespace path -2. Construct a CreateNamespaceRequest with the namespace array and properties -3. POST to `/namespaces` endpoint -4. Return the created namespace properties +1. Parse the namespace identifier to extract the catalog (first level) and namespace levels +2. Validate that at least 2 levels are provided (catalog + namespace) +3. Construct a CreateNamespaceRequest with the namespace array and properties +4. POST to `/api/catalog/v1/{catalog}/namespaces` endpoint +5. Return the created namespace properties **Error Handling:** @@ -69,10 +75,11 @@ Lists child namespaces under a given parent namespace. The implementation: -1. Parse the parent namespace identifier -2. For root namespace: GET `/namespaces` -3. For nested namespace: GET `/namespaces/{parent}/namespaces` -4. Convert the response namespace arrays to dot-separated strings +1. Parse the parent namespace identifier to extract the catalog (first level) +2. Validate that at least 1 level (catalog) is provided +3. For catalog-level listing: GET `/api/catalog/v1/{catalog}/namespaces` +4. For nested namespace listing: GET `/api/catalog/v1/{catalog}/namespaces/{parent}/namespaces` +5. Convert the response namespace arrays to dot-separated strings, prefixing with the catalog name **Error Handling:** @@ -84,9 +91,10 @@ Retrieves properties and metadata for a namespace. The implementation: -1. Parse the namespace identifier -2. GET `/namespaces/{namespace}` with URL-encoded namespace path -3. Return the namespace properties +1. Parse the namespace identifier to extract the catalog (first level) and namespace path +2. Validate that at least 2 levels are provided (catalog + namespace) +3. GET `/api/catalog/v1/{catalog}/namespaces/{namespace}` with URL-encoded namespace path +4. Return the namespace properties **Error Handling:** @@ -98,8 +106,9 @@ Removes a namespace from Polaris. Only RESTRICT mode is supported; CASCADE mode The implementation: -1. Parse the namespace identifier -2. DELETE `/namespaces/{namespace}` with URL-encoded namespace path +1. Parse the namespace identifier to extract the catalog (first level) and namespace path +2. Validate that at least 2 levels are provided (catalog + namespace) +3. DELETE `/api/catalog/v1/{catalog}/namespaces/{namespace}` with URL-encoded namespace path **Error Handling:** @@ -115,15 +124,16 @@ Declares a new Lance table in Polaris without creating the underlying data. The implementation: -1. Parse the table identifier to extract namespace and table name -2. Construct a CreateGenericTableRequest with: +1. Parse the table identifier to extract catalog (first level), namespace (middle levels), and table name (last level) +2. Validate that at least 3 levels are provided (catalog + namespace + table) +3. Construct a CreateGenericTableRequest with: - `name`: the table name - `format`: `lance` - `base-location`: the specified location - `doc`: optional description from properties - `properties`: table properties including `table_type=lance` -3. POST to `/namespaces/{namespace}/generic-tables` -4. Return the created table location and properties +4. POST to `/api/catalog/polaris/v1/{catalog}/namespaces/{namespace}/generic-tables` +5. Return the created table location and properties **Error Handling:** @@ -135,9 +145,10 @@ Lists all Lance tables in a namespace. The implementation: -1. Parse the namespace identifier -2. GET `/namespaces/{namespace}/generic-tables` -3. Extract table names from the response identifiers +1. Parse the namespace identifier to extract the catalog (first level) and namespace path +2. Validate that at least 2 levels are provided (catalog + namespace) +3. GET `/api/catalog/polaris/v1/{catalog}/namespaces/{namespace}/generic-tables` +4. Extract table names from the response identifiers **Error Handling:** @@ -149,10 +160,11 @@ Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is sup The implementation: -1. Parse the table identifier to extract namespace and table name -2. GET `/namespaces/{namespace}/generic-tables/{table}` -3. Verify the table format is `lance` -4. Return the table location from `base-location` and storage_options from `properties` +1. Parse the table identifier to extract catalog (first level), namespace (middle levels), and table name (last level) +2. Validate that at least 3 levels are provided (catalog + namespace + table) +3. GET `/api/catalog/polaris/v1/{catalog}/namespaces/{namespace}/generic-tables/{table}` +4. Verify the table format is `lance` +5. Return the table location from `base-location` and storage_options from `properties` **Error Handling:** @@ -168,8 +180,9 @@ Removes a Lance table registration from Polaris without deleting the underlying The implementation: -1. Parse the table identifier to extract namespace and table name -2. DELETE `/namespaces/{namespace}/generic-tables/{table}` +1. Parse the table identifier to extract catalog (first level), namespace (middle levels), and table name (last level) +2. Validate that at least 3 levels are provided (catalog + namespace + table) +3. DELETE `/api/catalog/polaris/v1/{catalog}/namespaces/{namespace}/generic-tables/{table}` **Error Handling:** diff --git a/java/Makefile b/java/Makefile index 7c9141a..cb74c28 100644 --- a/java/Makefile +++ b/java/Makefile @@ -151,7 +151,7 @@ integ-test-hive3: .PHONY: integ-test-polaris integ-test-polaris: - ./mvnw test -pl lance-namespace-polaris -Dtest="*IntegrationTest" -DfailIfNoTests=false + ./mvnw test -pl lance-namespace-polaris -Dtest="*Integration" -DfailIfNoTests=false .PHONY: integ-test-unity integ-test-unity: diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisModels.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisModels.java index 24fcbbe..595da3c 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisModels.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisModels.java @@ -180,21 +180,21 @@ public void setTable(GenericTable table) { /** Table identifier. */ @JsonIgnoreProperties(ignoreUnknown = true) public static class TableIdentifier { - private String namespace; + private List namespace; private String name; public TableIdentifier() {} - public TableIdentifier(String namespace, String name) { + public TableIdentifier(List namespace, String name) { this.namespace = namespace; this.name = name; } - public String getNamespace() { + public List getNamespace() { return namespace; } - public void setNamespace(String namespace) { + public void setNamespace(List namespace) { this.namespace = namespace; } @@ -339,11 +339,11 @@ public static class ListNamespacesResponse { @JsonProperty("next-page-token") private String nextPageToken; - private List namespaces; + private List> namespaces; public ListNamespacesResponse() {} - public ListNamespacesResponse(String nextPageToken, List namespaces) { + public ListNamespacesResponse(String nextPageToken, List> namespaces) { this.nextPageToken = nextPageToken; this.namespaces = namespaces; } @@ -356,32 +356,13 @@ public void setNextPageToken(String nextPageToken) { this.nextPageToken = nextPageToken; } - public List getNamespaces() { + public List> getNamespaces() { return namespaces; } - public void setNamespaces(List namespaces) { + public void setNamespaces(List> namespaces) { this.namespaces = namespaces; } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Namespace { - private List namespace; - - public Namespace() {} - - public Namespace(List namespace) { - this.namespace = namespace; - } - - public List getNamespace() { - return namespace; - } - - public void setNamespace(List namespace) { - this.namespace = namespace; - } - } } /** Create namespace request. */ diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java index 5f77297..88530f4 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java @@ -99,18 +99,23 @@ public String namespaceId() { public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - namespaceId.levels() >= 1, "Namespace must have at least one level"); + namespaceId.levels() >= 2, "Namespace must have at least catalog and namespace levels"); try { - List namespace = namespaceId.listStyleId(); + List parts = namespaceId.listStyleId(); + String catalog = parts.get(0); + List namespace = parts.subList(1, parts.size()); PolarisModels.CreateNamespaceRequest polarisRequest = new PolarisModels.CreateNamespaceRequest(namespace, request.getProperties()); PolarisModels.NamespaceResponse response = - restClient.post("/namespaces", polarisRequest, PolarisModels.NamespaceResponse.class); + restClient.post( + "/v1/" + catalog + "/namespaces", + polarisRequest, + PolarisModels.NamespaceResponse.class); - LOG.info("Created namespace: {}", String.join(".", namespace)); + LOG.info("Created namespace: {}.{}", catalog, String.join(".", namespace)); CreateNamespaceResponse result = new CreateNamespaceResponse(); result.setProperties(response.getProperties()); @@ -128,13 +133,18 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest request) { ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - namespaceId.levels() >= 1, "Namespace must have at least one level"); + namespaceId.levels() >= 2, "Namespace must have at least catalog and namespace levels"); try { - String namespacePath = namespaceId.stringStyleId(); + List parts = namespaceId.listStyleId(); + String catalog = parts.get(0); + List namespaceParts = parts.subList(1, parts.size()); + String namespacePath = String.join(".", namespaceParts); PolarisModels.NamespaceResponse response = - restClient.get("/namespaces/" + namespacePath, PolarisModels.NamespaceResponse.class); + restClient.get( + "/v1/" + catalog + "/namespaces/" + namespacePath, + PolarisModels.NamespaceResponse.class); DescribeNamespaceResponse result = new DescribeNamespaceResponse(); result.setProperties(response.getProperties()); @@ -154,10 +164,15 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ? ObjectIdentifier.of(request.getId()) : ObjectIdentifier.of(Collections.emptyList()); + ValidationUtil.checkArgument(parentId.levels() >= 1, "Must specify at least the catalog"); + try { - String path = "/namespaces"; - if (!parentId.isRoot()) { - path += "/" + parentId.stringStyleId() + "/namespaces"; + List parts = parentId.listStyleId(); + String catalog = parts.get(0); + String path = "/v1/" + catalog + "/namespaces"; + if (parts.size() > 1) { + List namespaceParts = parts.subList(1, parts.size()); + path = "/v1/" + catalog + "/namespaces/" + String.join(".", namespaceParts) + "/namespaces"; } PolarisModels.ListNamespacesResponse response = @@ -166,8 +181,11 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ListNamespacesResponse result = new ListNamespacesResponse(); Set namespaceSet = new LinkedHashSet<>(); if (response.getNamespaces() != null) { - for (PolarisModels.ListNamespacesResponse.Namespace ns : response.getNamespaces()) { - namespaceSet.add(String.join(".", ns.getNamespace())); + for (List ns : response.getNamespaces()) { + List fullNs = new java.util.ArrayList<>(); + fullNs.add(catalog); + fullNs.addAll(ns); + namespaceSet.add(String.join(".", fullNs)); } } result.setNamespaces(namespaceSet); @@ -181,12 +199,16 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - namespaceId.levels() >= 1, "Namespace must have at least one level"); + namespaceId.levels() >= 2, "Namespace must have at least catalog and namespace levels"); try { - String namespacePath = namespaceId.stringStyleId(); - restClient.delete("/namespaces/" + namespacePath); - LOG.info("Dropped namespace: {}", namespacePath); + List parts = namespaceId.listStyleId(); + String catalog = parts.get(0); + List namespaceParts = parts.subList(1, parts.size()); + String namespacePath = String.join(".", namespaceParts); + + restClient.delete("/v1/" + catalog + "/namespaces/" + namespacePath); + LOG.info("Dropped namespace: {}.{}", catalog, namespacePath); return new DropNamespaceResponse(); } catch (RestClientException e) { if (e.isNotFound()) { @@ -200,11 +222,16 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { public void namespaceExists(NamespaceExistsRequest request) { ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - namespaceId.levels() >= 1, "Namespace must have at least one level"); + namespaceId.levels() >= 2, "Namespace must have at least catalog and namespace levels"); try { - String namespacePath = namespaceId.stringStyleId(); - restClient.get("/namespaces/" + namespacePath, PolarisModels.NamespaceResponse.class); + List parts = namespaceId.listStyleId(); + String catalog = parts.get(0); + List namespaceParts = parts.subList(1, parts.size()); + String namespacePath = String.join(".", namespaceParts); + + restClient.get( + "/v1/" + catalog + "/namespaces/" + namespacePath, PolarisModels.NamespaceResponse.class); } catch (RestClientException e) { if (e.isNotFound()) { throw new NamespaceNotFoundException("Namespace not found: " + namespaceId.stringStyleId()); @@ -217,16 +244,22 @@ public void namespaceExists(NamespaceExistsRequest request) { public void tableExists(TableExistsRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least 2 levels"); + tableId.levels() >= 3, "Table identifier must have catalog, namespace, and table name"); try { List parts = tableId.listStyleId(); + String catalog = parts.get(0); String tableName = parts.get(parts.size() - 1); - List namespaceParts = parts.subList(0, parts.size() - 1); + List namespaceParts = parts.subList(1, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); restClient.get( - "/namespaces/" + namespacePath + "/generic-tables/" + tableName, + "/polaris/v1/" + + catalog + + "/namespaces/" + + namespacePath + + "/generic-tables/" + + tableName, PolarisModels.LoadGenericTableResponse.class); } catch (RestClientException e) { if (e.isNotFound()) { @@ -240,12 +273,13 @@ public void tableExists(TableExistsRequest request) { public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least 2 levels"); + tableId.levels() >= 3, "Table identifier must have catalog, namespace, and table name"); try { List parts = tableId.listStyleId(); + String catalog = parts.get(0); String tableName = parts.get(parts.size() - 1); - List namespaceParts = parts.subList(0, parts.size() - 1); + List namespaceParts = parts.subList(1, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); Map properties = new HashMap<>(); @@ -258,11 +292,11 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request PolarisModels.LoadGenericTableResponse response = restClient.post( - "/namespaces/" + namespacePath + "/generic-tables", + "/polaris/v1/" + catalog + "/namespaces/" + namespacePath + "/generic-tables", tableRequest, PolarisModels.LoadGenericTableResponse.class); - LOG.info("Created Lance table: {}.{}", namespacePath, tableName); + LOG.info("Created Lance table: {}.{}.{}", catalog, namespacePath, tableName); CreateEmptyTableResponse result = new CreateEmptyTableResponse(); result.setLocation(response.getTable().getBaseLocation()); @@ -279,17 +313,23 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request public DescribeTableResponse describeTable(DescribeTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least 2 levels"); + tableId.levels() >= 3, "Table identifier must have catalog, namespace, and table name"); try { List parts = tableId.listStyleId(); + String catalog = parts.get(0); String tableName = parts.get(parts.size() - 1); - List namespaceParts = parts.subList(0, parts.size() - 1); + List namespaceParts = parts.subList(1, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); PolarisModels.LoadGenericTableResponse response = restClient.get( - "/namespaces/" + namespacePath + "/generic-tables/" + tableName, + "/polaris/v1/" + + catalog + + "/namespaces/" + + namespacePath + + "/generic-tables/" + + tableName, PolarisModels.LoadGenericTableResponse.class); PolarisModels.GenericTable table = response.getTable(); @@ -317,14 +357,17 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { public ListTablesResponse listTables(ListTablesRequest request) { ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - namespaceId.levels() >= 1, "Namespace must have at least one level"); + namespaceId.levels() >= 2, "Must specify at least catalog and namespace"); try { - String namespacePath = namespaceId.stringStyleId(); + List parts = namespaceId.listStyleId(); + String catalog = parts.get(0); + List namespaceParts = parts.subList(1, parts.size()); + String namespacePath = String.join(".", namespaceParts); PolarisModels.ListGenericTablesResponse response = restClient.get( - "/namespaces/" + namespacePath + "/generic-tables", + "/polaris/v1/" + catalog + "/namespaces/" + namespacePath + "/generic-tables", PolarisModels.ListGenericTablesResponse.class); ListTablesResponse result = new ListTablesResponse(); @@ -348,21 +391,33 @@ public ListTablesResponse listTables(ListTablesRequest request) { public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least 2 levels"); + tableId.levels() >= 3, "Table identifier must have catalog, namespace, and table name"); try { List parts = tableId.listStyleId(); + String catalog = parts.get(0); String tableName = parts.get(parts.size() - 1); - List namespaceParts = parts.subList(0, parts.size() - 1); + List namespaceParts = parts.subList(1, parts.size() - 1); String namespacePath = String.join(".", namespaceParts); PolarisModels.LoadGenericTableResponse getResponse = restClient.get( - "/namespaces/" + namespacePath + "/generic-tables/" + tableName, + "/polaris/v1/" + + catalog + + "/namespaces/" + + namespacePath + + "/generic-tables/" + + tableName, PolarisModels.LoadGenericTableResponse.class); String location = getResponse.getTable().getBaseLocation(); - restClient.delete("/namespaces/" + namespacePath + "/generic-tables/" + tableName); + restClient.delete( + "/polaris/v1/" + + catalog + + "/namespaces/" + + namespacePath + + "/generic-tables/" + + tableName); DeregisterTableResponse result = new DeregisterTableResponse(); result.setLocation(location); diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java index 9fd8e05..26fa519 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespaceConfig.java @@ -100,10 +100,10 @@ public int getMaxRetries() { return maxRetries; } - /** Get the full API URL for Polaris catalog operations. Format: {endpoint}/api/catalog/v1 */ + /** Get the full API URL for Polaris catalog operations. Format: {endpoint}/api/catalog */ public String getFullApiUrl() { String baseUrl = endpoint.endsWith("/") ? endpoint.substring(0, endpoint.length() - 1) : endpoint; - return baseUrl + "/api/catalog/v1"; + return baseUrl + "/api/catalog"; } } diff --git a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java index a01a326..55d7622 100644 --- a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java +++ b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespace.java @@ -47,6 +47,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -116,7 +117,7 @@ public void testCreateNamespace() throws IOException { mockResponse.setProperties(Collections.singletonMap("key", "value")); when(restClient.post( - eq("/namespaces"), + eq("/v1/test_catalog/namespaces"), any(PolarisModels.CreateNamespaceRequest.class), eq(PolarisModels.NamespaceResponse.class))) .thenReturn(mockResponse); @@ -138,7 +139,7 @@ public void testDescribeNamespace() throws IOException { mockResponse.setProperties(Collections.singletonMap("description", "test schema")); when(restClient.get( - eq("/namespaces/test_catalog.schema1"), eq(PolarisModels.NamespaceResponse.class))) + eq("/v1/test_catalog/namespaces/schema1"), eq(PolarisModels.NamespaceResponse.class))) .thenReturn(mockResponse); DescribeNamespaceRequest request = new DescribeNamespaceRequest(); @@ -153,18 +154,16 @@ public void testDescribeNamespace() throws IOException { @Test public void testListNamespaces() throws IOException { PolarisModels.ListNamespacesResponse mockResponse = new PolarisModels.ListNamespacesResponse(); - PolarisModels.ListNamespacesResponse.Namespace ns1 = - new PolarisModels.ListNamespacesResponse.Namespace(); - ns1.setNamespace(Arrays.asList("test_catalog", "schema1")); - PolarisModels.ListNamespacesResponse.Namespace ns2 = - new PolarisModels.ListNamespacesResponse.Namespace(); - ns2.setNamespace(Arrays.asList("test_catalog", "schema2")); - mockResponse.setNamespaces(Arrays.asList(ns1, ns2)); - - when(restClient.get(eq("/namespaces"), eq(PolarisModels.ListNamespacesResponse.class))) + List> namespaces = + Arrays.asList(Arrays.asList("schema1"), Arrays.asList("schema2")); + mockResponse.setNamespaces(namespaces); + + when(restClient.get( + eq("/v1/test_catalog/namespaces"), eq(PolarisModels.ListNamespacesResponse.class))) .thenReturn(mockResponse); ListNamespacesRequest request = new ListNamespacesRequest(); + request.setId(Collections.singletonList("test_catalog")); ListNamespacesResponse response = namespace.listNamespaces(request); @@ -179,14 +178,14 @@ public void testDropNamespace() throws IOException { DropNamespaceResponse response = namespace.dropNamespace(request); - verify(restClient).delete("/namespaces/test_catalog.schema1"); + verify(restClient).delete("/v1/test_catalog/namespaces/schema1"); // Response doesn't have getId() method, just verify the delete was called } @Test public void testNamespaceExists() throws IOException { when(restClient.get( - eq("/namespaces/test_catalog.schema1"), eq(PolarisModels.NamespaceResponse.class))) + eq("/v1/test_catalog/namespaces/schema1"), eq(PolarisModels.NamespaceResponse.class))) .thenReturn(new PolarisModels.NamespaceResponse()); NamespaceExistsRequest request = new NamespaceExistsRequest(); @@ -199,7 +198,7 @@ public void testNamespaceExists() throws IOException { @Test public void testNamespaceNotExists() throws IOException { when(restClient.get( - eq("/namespaces/test_catalog.schema1"), eq(PolarisModels.NamespaceResponse.class))) + eq("/v1/test_catalog/namespaces/schema1"), eq(PolarisModels.NamespaceResponse.class))) .thenThrow(new org.lance.namespace.rest.RestClientException(404, "Not Found")); NamespaceExistsRequest request = new NamespaceExistsRequest(); @@ -226,7 +225,7 @@ public void testCreateEmptyTable() throws IOException { mockResponse.setTable(mockTable); when(restClient.post( - eq("/namespaces/test_catalog.schema1/generic-tables"), + eq("/polaris/v1/test_catalog/namespaces/schema1/generic-tables"), any(PolarisModels.CreateGenericTableRequest.class), eq(PolarisModels.LoadGenericTableResponse.class))) .thenReturn(mockResponse); @@ -256,7 +255,7 @@ public void testDescribeTable() throws IOException { mockResponse.setTable(mockTable); when(restClient.get( - eq("/namespaces/test_catalog.schema1/generic-tables/test_table"), + eq("/polaris/v1/test_catalog/namespaces/schema1/generic-tables/test_table"), eq(PolarisModels.LoadGenericTableResponse.class))) .thenReturn(mockResponse); @@ -280,7 +279,7 @@ public void testDescribeTableNotLanceFormat() throws IOException { mockResponse.setTable(mockTable); when(restClient.get( - eq("/namespaces/test_catalog.schema1/generic-tables/test_table"), + eq("/polaris/v1/test_catalog/namespaces/schema1/generic-tables/test_table"), eq(PolarisModels.LoadGenericTableResponse.class))) .thenReturn(mockResponse); @@ -295,11 +294,11 @@ public void testDescribeTableNotLanceFormat() throws IOException { @Test public void testListTables() throws IOException { PolarisModels.TableIdentifier id1 = new PolarisModels.TableIdentifier(); - id1.setNamespace("test_catalog.schema1"); + id1.setNamespace(Collections.singletonList("schema1")); id1.setName("table1"); PolarisModels.TableIdentifier id2 = new PolarisModels.TableIdentifier(); - id2.setNamespace("test_catalog.schema1"); + id2.setNamespace(Collections.singletonList("schema1")); id2.setName("table2"); PolarisModels.ListGenericTablesResponse mockResponse = @@ -307,7 +306,7 @@ public void testListTables() throws IOException { mockResponse.setIdentifiers(Arrays.asList(id1, id2)); when(restClient.get( - eq("/namespaces/test_catalog.schema1/generic-tables"), + eq("/polaris/v1/test_catalog/namespaces/schema1/generic-tables"), eq(PolarisModels.ListGenericTablesResponse.class))) .thenReturn(mockResponse); @@ -332,7 +331,7 @@ public void testDeregisterTable() throws IOException { mockResponse.setTable(mockTable); when(restClient.get( - eq("/namespaces/test_catalog.schema1/generic-tables/test_table"), + eq("/polaris/v1/test_catalog/namespaces/schema1/generic-tables/test_table"), eq(PolarisModels.LoadGenericTableResponse.class))) .thenReturn(mockResponse); @@ -342,6 +341,7 @@ public void testDeregisterTable() throws IOException { DeregisterTableResponse response = namespace.deregisterTable(request); assertThat(response.getLocation()).isEqualTo("s3://bucket/path/to/table"); - verify(restClient).delete("/namespaces/test_catalog.schema1/generic-tables/test_table"); + verify(restClient) + .delete("/polaris/v1/test_catalog/namespaces/schema1/generic-tables/test_table"); } } diff --git a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java index 52f5641..e7a4804 100644 --- a/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java +++ b/java/lance-namespace-polaris/src/test/java/org/lance/namespace/polaris/TestPolarisNamespaceIntegration.java @@ -74,8 +74,8 @@ public class TestPolarisNamespaceIntegration { public static void checkPolarisAvailable() { try { // Try to check if Polaris API is available by checking a known endpoint - // We'll try the namespaces endpoint which should exist - URL url = new URL(POLARIS_ENDPOINT + "/api/catalog/v1/namespaces"); + // We'll try the namespaces endpoint with the test catalog warehouse + URL url = new URL(POLARIS_ENDPOINT + "/api/catalog/v1/test_catalog/namespaces"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(1000); @@ -224,9 +224,9 @@ public void testNamespaceOperations() { // List namespaces ListNamespacesRequest listRequest = new ListNamespacesRequest(); + listRequest.setId(Collections.singletonList(testCatalog)); ListNamespacesResponse listResponse = namespace.listNamespaces(listRequest); - assertThat(listResponse.getNamespaces()) - .anyMatch(ns -> ns.equals(Arrays.asList(testCatalog, testNamespace))); + assertThat(listResponse.getNamespaces()).contains(testCatalog + "." + testNamespace); // Drop namespace DropNamespaceRequest dropRequest = new DropNamespaceRequest(); @@ -236,7 +236,7 @@ public void testNamespaceOperations() { // Verify namespace doesn't exist assertThatThrownBy(() -> namespace.namespaceExists(existsRequest)) .isInstanceOf(LanceNamespaceException.class) - .hasMessageContaining("404"); + .hasMessageContaining("not found"); } @Test @@ -283,7 +283,7 @@ public void testTableOperations() { // Verify table doesn't exist assertThatThrownBy(() -> namespace.tableExists(existsRequest)) .isInstanceOf(LanceNamespaceException.class) - .hasMessageContaining("404"); + .hasMessageContaining("not found"); } @Test diff --git a/python/Makefile b/python/Makefile index 7d25808..f4890dd 100644 --- a/python/Makefile +++ b/python/Makefile @@ -84,8 +84,8 @@ test-iceberg: .PHONY: lint-polaris lint-polaris: - uv run ruff check src/lance_namespace_impls/polaris.py tests/test_polaris.py - uv run ruff format --check src/lance_namespace_impls/polaris.py tests/test_polaris.py + uv run ruff check src/lance_namespace_impls/polaris.py tests/test_polaris.py tests/test_polaris_integration.py + uv run ruff format --check src/lance_namespace_impls/polaris.py tests/test_polaris.py tests/test_polaris_integration.py .PHONY: install-polaris install-polaris: @@ -143,7 +143,7 @@ integ-test-hive: .PHONY: integ-test-polaris integ-test-polaris: - uv run pytest tests/test_polaris.py -m integration + uv run pytest tests/test_polaris_integration.py -v .PHONY: integ-test-unity integ-test-unity: diff --git a/python/pyproject.toml b/python/pyproject.toml index 2bbe336..34f8b4f 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -43,6 +43,11 @@ dev = [ "pytest-cov>=4.0.0", ] +[tool.pytest.ini_options] +markers = [ + "integration: marks tests as integration tests (deselect with '-m \"not integration\"')", +] + [tool.hatch.build.targets.wheel] packages = ["src/lance_namespace_impls"] diff --git a/python/src/lance_namespace_impls/polaris.py b/python/src/lance_namespace_impls/polaris.py index 4ae373a..6315290 100644 --- a/python/src/lance_namespace_impls/polaris.py +++ b/python/src/lance_namespace_impls/polaris.py @@ -4,7 +4,7 @@ import logging from dataclasses import dataclass -from typing import Any, Dict, List, Optional +from typing import Dict, List, Optional from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( @@ -72,8 +72,8 @@ def __init__(self, properties: Dict[str, str]): self.root = properties.get(self.ROOT, "/tmp/lance") def get_full_api_url(self) -> str: - """Get the full API URL.""" - return self.endpoint.rstrip("/") + """Get the full API URL for Polaris catalog operations.""" + return self.endpoint.rstrip("/") + "/api/catalog" class PolarisNamespace(LanceNamespace): @@ -110,12 +110,18 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo """List namespaces.""" ns_id = self._parse_identifier(request.id) + if not ns_id: + raise InvalidInputException("Must specify at least the catalog") + try: - if not ns_id: - path = "/namespaces" + catalog = ns_id[0] + if len(ns_id) == 1: + # List namespaces at catalog level + path = f"/v1/{catalog}/namespaces" else: - parent_path = ".".join(ns_id) - path = f"/namespaces/{parent_path}/namespaces" + # List nested namespaces + parent_path = ".".join(ns_id[1:]) + path = f"/v1/{catalog}/namespaces/{parent_path}/namespaces" response = self.rest_client.get(path) @@ -123,7 +129,9 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo if response and "namespaces" in response: for ns in response["namespaces"]: if ns: - namespaces.append(".".join(ns)) + # Prefix with catalog name + full_ns = [catalog] + list(ns) + namespaces.append(".".join(full_ns)) namespaces = sorted(set(namespaces)) @@ -131,6 +139,8 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo except RestClientException as e: raise InternalException(f"Failed to list namespaces: {e}") + except InvalidInputException: + raise except Exception as e: raise InternalException(f"Failed to list namespaces: {e}") @@ -140,18 +150,25 @@ def create_namespace( """Create a new namespace.""" ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least catalog and namespace levels" + ) try: + catalog = ns_id[0] + namespace = ns_id[1:] + create_request = { - "namespace": ns_id, + "namespace": namespace, "properties": request.properties or {}, } - response = self.rest_client.post("/namespaces", create_request) + response = self.rest_client.post( + f"/v1/{catalog}/namespaces", create_request + ) - logger.info(f"Created namespace: {'.'.join(ns_id)}") + logger.info(f"Created namespace: {catalog}.{'.'.join(namespace)}") properties = response.get("properties") if response else {} return CreateNamespaceResponse(properties=properties) @@ -173,12 +190,17 @@ def describe_namespace( """Describe a namespace.""" ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least catalog and namespace levels" + ) try: - namespace_path = ".".join(ns_id) - response = self.rest_client.get(f"/namespaces/{namespace_path}") + catalog = ns_id[0] + namespace_path = ".".join(ns_id[1:]) + response = self.rest_client.get( + f"/v1/{catalog}/namespaces/{namespace_path}" + ) properties = response.get("properties") if response else {} return DescribeNamespaceResponse(properties=properties) @@ -204,14 +226,17 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse """Drop a namespace. Only RESTRICT mode is supported.""" ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least catalog and namespace levels" + ) try: - namespace_path = ".".join(ns_id) - self.rest_client.delete(f"/namespaces/{namespace_path}") + catalog = ns_id[0] + namespace_path = ".".join(ns_id[1:]) + self.rest_client.delete(f"/v1/{catalog}/namespaces/{namespace_path}") - logger.info(f"Dropped namespace: {'.'.join(ns_id)}") + logger.info(f"Dropped namespace: {catalog}.{namespace_path}") return DropNamespaceResponse(properties={}) @@ -228,13 +253,14 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a namespace.""" ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException("Must specify at least catalog and namespace") try: - namespace_path = ".".join(ns_id) + catalog = ns_id[0] + namespace_path = ".".join(ns_id[1:]) response = self.rest_client.get( - f"/namespaces/{namespace_path}/generic-tables" + f"/polaris/v1/{catalog}/namespaces/{namespace_path}/generic-tables" ) tables = [] @@ -265,18 +291,21 @@ def create_empty_table( """Create an empty table (metadata only operation).""" table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have catalog, namespace, and table name" ) - namespace = table_id[:-1] + catalog = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: table_path = request.location if not table_path: - table_path = f"{self.config.root}/{'/'.join(namespace)}/{table_name}" + table_path = ( + f"{self.config.root}/{'/'.join(table_id[:-1])}/{table_name}" + ) properties = {self.TABLE_TYPE_KEY: self.TABLE_FORMAT_LANCE} @@ -288,8 +317,9 @@ def create_empty_table( } namespace_path = ".".join(namespace) - response = self.rest_client.post( - f"/namespaces/{namespace_path}/generic-tables", create_request + self.rest_client.post( + f"/polaris/v1/{catalog}/namespaces/{namespace_path}/generic-tables", + create_request, ) logger.info(f"Created table: {'.'.join(table_id)}") @@ -303,7 +333,7 @@ def create_empty_table( ) if e.is_not_found(): raise NamespaceNotFoundException( - f"Namespace not found: {'.'.join(namespace)}" + f"Namespace not found: {catalog}.{'.'.join(namespace)}" ) raise InternalException(f"Failed to create empty table: {e}") except ( @@ -322,25 +352,24 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse """ table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have catalog, namespace, and table name" ) - namespace = table_id[:-1] + catalog = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: namespace_path = ".".join(namespace) response = self.rest_client.get( - f"/namespaces/{namespace_path}/generic-tables/{table_name}" + f"/polaris/v1/{catalog}/namespaces/{namespace_path}/generic-tables/{table_name}" ) if not response or "table" not in response: - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") table = response["table"] table_format = table.get("format", "") @@ -352,14 +381,12 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse return DescribeTableResponse( location=table.get("base-location"), - storage_options=table.get("properties", {}) + storage_options=table.get("properties", {}), ) except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to describe table: {e}") except (TableNotFoundException, InvalidInputException): raise @@ -378,19 +405,20 @@ def deregister_table( """Deregister a table (remove from catalog without deleting data).""" table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have catalog, namespace, and table name" ) - namespace = table_id[:-1] + catalog = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: namespace_path = ".".join(namespace) response = self.rest_client.get( - f"/namespaces/{namespace_path}/generic-tables/{table_name}" + f"/polaris/v1/{catalog}/namespaces/{namespace_path}/generic-tables/{table_name}" ) table_location = None @@ -398,7 +426,7 @@ def deregister_table( table_location = response["table"].get("base-location") self.rest_client.delete( - f"/namespaces/{namespace_path}/generic-tables/{table_name}" + f"/polaris/v1/{catalog}/namespaces/{namespace_path}/generic-tables/{table_name}" ) logger.info(f"Deregistered table: {'.'.join(table_id)}") @@ -407,9 +435,7 @@ def deregister_table( except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to deregister table: {e}") except (TableNotFoundException, InvalidInputException): raise diff --git a/python/tests/test_polaris.py b/python/tests/test_polaris.py index fda3e72..3e2d81f 100644 --- a/python/tests/test_polaris.py +++ b/python/tests/test_polaris.py @@ -16,7 +16,6 @@ TableNotFoundException, TableAlreadyExistsException, InvalidInputException, - InternalException, ) from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, @@ -73,7 +72,9 @@ def test_get_full_api_url(self): properties = {"polaris.endpoint": "https://polaris.example.com/"} config = PolarisNamespaceConfig(properties) - self.assertEqual(config.get_full_api_url(), "https://polaris.example.com") + self.assertEqual( + config.get_full_api_url(), "https://polaris.example.com/api/catalog" + ) class TestPolarisNamespace(unittest.TestCase): @@ -99,24 +100,25 @@ def test_namespace_id(self, mock_rest_client_class): self.assertIn("polaris.example.com", ns_id) @patch("lance_namespace_impls.polaris.RestClient") - def test_list_namespaces_top_level(self, mock_rest_client_class): - """Test listing top-level namespaces.""" + def test_list_namespaces_catalog_level(self, mock_rest_client_class): + """Test listing namespaces at catalog level.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - mock_client.get.return_value = { - "namespaces": [["ns1"], ["ns2"], ["ns3"]] - } + mock_client.get.return_value = {"namespaces": [["ns1"], ["ns2"], ["ns3"]]} namespace = PolarisNamespace(**self.properties) request = ListNamespacesRequest() - request.id = [] + request.id = ["test_catalog"] response = namespace.list_namespaces(request) - self.assertEqual(sorted(response.namespaces), ["ns1", "ns2", "ns3"]) - mock_client.get.assert_called_once_with("/namespaces") + self.assertEqual( + sorted(response.namespaces), + ["test_catalog.ns1", "test_catalog.ns2", "test_catalog.ns3"], + ) + mock_client.get.assert_called_once_with("/v1/test_catalog/namespaces") @patch("lance_namespace_impls.polaris.RestClient") def test_list_namespaces_nested(self, mock_rest_client_class): @@ -131,12 +133,17 @@ def test_list_namespaces_nested(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = ListNamespacesRequest() - request.id = ["parent"] + request.id = ["test_catalog", "parent"] response = namespace.list_namespaces(request) - self.assertEqual(sorted(response.namespaces), ["parent.child1", "parent.child2"]) - mock_client.get.assert_called_once_with("/namespaces/parent/namespaces") + self.assertEqual( + sorted(response.namespaces), + ["test_catalog.parent.child1", "test_catalog.parent.child2"], + ) + mock_client.get.assert_called_once_with( + "/v1/test_catalog/namespaces/parent/namespaces" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_create_namespace(self, mock_rest_client_class): @@ -149,13 +156,16 @@ def test_create_namespace(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = CreateNamespaceRequest() - request.id = ["test_namespace"] + request.id = ["test_catalog", "test_namespace"] request.properties = {"key": "value"} response = namespace.create_namespace(request) self.assertEqual(response.properties, {"key": "value"}) - mock_client.post.assert_called_once() + mock_client.post.assert_called_once_with( + "/v1/test_catalog/namespaces", + {"namespace": ["test_namespace"], "properties": {"key": "value"}}, + ) @patch("lance_namespace_impls.polaris.RestClient") def test_create_namespace_already_exists(self, mock_rest_client_class): @@ -164,13 +174,13 @@ def test_create_namespace_already_exists(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.post.side_effect = RestClientException( - "Conflict", status_code=409, response_body="" + status_code=409, response_body="Conflict" ) namespace = PolarisNamespace(**self.properties) request = CreateNamespaceRequest() - request.id = ["existing_namespace"] + request.id = ["test_catalog", "existing_namespace"] with self.assertRaises(NamespaceAlreadyExistsException): namespace.create_namespace(request) @@ -186,12 +196,14 @@ def test_describe_namespace(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = DescribeNamespaceRequest() - request.id = ["test_namespace"] + request.id = ["test_catalog", "test_namespace"] response = namespace.describe_namespace(request) self.assertEqual(response.properties, {"key": "value"}) - mock_client.get.assert_called_once_with("/namespaces/test_namespace") + mock_client.get.assert_called_once_with( + "/v1/test_catalog/namespaces/test_namespace" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_describe_namespace_not_found(self, mock_rest_client_class): @@ -200,13 +212,13 @@ def test_describe_namespace_not_found(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.get.side_effect = RestClientException( - "Not found", status_code=404, response_body="" + status_code=404, response_body="Not found" ) namespace = PolarisNamespace(**self.properties) request = DescribeNamespaceRequest() - request.id = ["nonexistent"] + request.id = ["test_catalog", "nonexistent"] with self.assertRaises(NamespaceNotFoundException): namespace.describe_namespace(request) @@ -220,12 +232,14 @@ def test_drop_namespace(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = DropNamespaceRequest() - request.id = ["test_namespace"] + request.id = ["test_catalog", "test_namespace"] response = namespace.drop_namespace(request) self.assertIsNotNone(response) - mock_client.delete.assert_called_once_with("/namespaces/test_namespace") + mock_client.delete.assert_called_once_with( + "/v1/test_catalog/namespaces/test_namespace" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_drop_namespace_not_found(self, mock_rest_client_class): @@ -234,13 +248,13 @@ def test_drop_namespace_not_found(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.delete.side_effect = RestClientException( - "Not found", status_code=404, response_body="" + status_code=404, response_body="Not found" ) namespace = PolarisNamespace(**self.properties) request = DropNamespaceRequest() - request.id = ["nonexistent"] + request.id = ["test_catalog", "nonexistent"] response = namespace.drop_namespace(request) @@ -263,11 +277,14 @@ def test_list_tables(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = ListTablesRequest() - request.id = ["test_namespace"] + request.id = ["test_catalog", "test_namespace"] response = namespace.list_tables(request) self.assertEqual(sorted(response.tables), ["table1", "table2", "table3"]) + mock_client.get.assert_called_once_with( + "/polaris/v1/test_catalog/namespaces/test_namespace/generic-tables" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_create_empty_table(self, mock_rest_client_class): @@ -280,14 +297,15 @@ def test_create_empty_table(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = CreateEmptyTableRequest() - request.id = ["test_namespace", "test_table"] + request.id = ["test_catalog", "test_namespace", "test_table"] request.location = None response = namespace.create_empty_table(request) self.assertEqual( - response.location, "/data/lance/test_namespace/test_table" + response.location, "/data/lance/test_catalog/test_namespace/test_table" ) + mock_client.post.assert_called_once() @patch("lance_namespace_impls.polaris.RestClient") def test_create_empty_table_with_location(self, mock_rest_client_class): @@ -300,12 +318,21 @@ def test_create_empty_table_with_location(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = CreateEmptyTableRequest() - request.id = ["test_namespace", "test_table"] + request.id = ["test_catalog", "test_namespace", "test_table"] request.location = "/custom/path/test_table" response = namespace.create_empty_table(request) self.assertEqual(response.location, "/custom/path/test_table") + mock_client.post.assert_called_once_with( + "/polaris/v1/test_catalog/namespaces/test_namespace/generic-tables", + { + "name": "test_table", + "format": "lance", + "base-location": "/custom/path/test_table", + "properties": {"table_type": "lance"}, + }, + ) @patch("lance_namespace_impls.polaris.RestClient") def test_create_empty_table_already_exists(self, mock_rest_client_class): @@ -314,13 +341,13 @@ def test_create_empty_table_already_exists(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.post.side_effect = RestClientException( - "Conflict", status_code=409, response_body="" + status_code=409, response_body="Conflict" ) namespace = PolarisNamespace(**self.properties) request = CreateEmptyTableRequest() - request.id = ["test_namespace", "existing_table"] + request.id = ["test_catalog", "test_namespace", "existing_table"] with self.assertRaises(TableAlreadyExistsException): namespace.create_empty_table(request) @@ -342,12 +369,15 @@ def test_describe_table(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = DescribeTableRequest() - request.id = ["test_namespace", "test_table"] + request.id = ["test_catalog", "test_namespace", "test_table"] response = namespace.describe_table(request) self.assertEqual(response.location, "/data/lance/ns/table") self.assertEqual(response.storage_options, {"key": "value"}) + mock_client.get.assert_called_once_with( + "/polaris/v1/test_catalog/namespaces/test_namespace/generic-tables/test_table" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_describe_table_not_lance(self, mock_rest_client_class): @@ -366,7 +396,7 @@ def test_describe_table_not_lance(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = DescribeTableRequest() - request.id = ["test_namespace", "test_table"] + request.id = ["test_catalog", "test_namespace", "test_table"] with self.assertRaises(InvalidInputException): namespace.describe_table(request) @@ -378,13 +408,13 @@ def test_describe_table_not_found(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.get.side_effect = RestClientException( - "Not found", status_code=404, response_body="" + status_code=404, response_body="Not found" ) namespace = PolarisNamespace(**self.properties) request = DescribeTableRequest() - request.id = ["test_namespace", "nonexistent"] + request.id = ["test_catalog", "test_namespace", "nonexistent"] with self.assertRaises(TableNotFoundException): namespace.describe_table(request) @@ -402,12 +432,17 @@ def test_deregister_table(self, mock_rest_client_class): namespace = PolarisNamespace(**self.properties) request = DeregisterTableRequest() - request.id = ["test_namespace", "test_table"] + request.id = ["test_catalog", "test_namespace", "test_table"] response = namespace.deregister_table(request) self.assertEqual(response.location, "/data/lance/ns/table") - mock_client.delete.assert_called_once() + mock_client.get.assert_called_once_with( + "/polaris/v1/test_catalog/namespaces/test_namespace/generic-tables/test_table" + ) + mock_client.delete.assert_called_once_with( + "/polaris/v1/test_catalog/namespaces/test_namespace/generic-tables/test_table" + ) @patch("lance_namespace_impls.polaris.RestClient") def test_deregister_table_not_found(self, mock_rest_client_class): @@ -416,13 +451,13 @@ def test_deregister_table_not_found(self, mock_rest_client_class): mock_rest_client_class.return_value = mock_client mock_client.get.side_effect = RestClientException( - "Not found", status_code=404, response_body="" + status_code=404, response_body="Not found" ) namespace = PolarisNamespace(**self.properties) request = DeregisterTableRequest() - request.id = ["test_namespace", "nonexistent"] + request.id = ["test_catalog", "test_namespace", "nonexistent"] with self.assertRaises(TableNotFoundException): namespace.deregister_table(request) @@ -443,17 +478,17 @@ def test_invalid_table_id(self): namespace = PolarisNamespace(**self.properties) request = CreateEmptyTableRequest() - request.id = ["only_namespace"] + request.id = ["catalog", "only_namespace"] # Missing table name with self.assertRaises(InvalidInputException): namespace.create_empty_table(request) def test_invalid_namespace_id(self): - """Test that namespace operations fail with empty identifiers.""" + """Test that namespace operations fail with invalid identifiers.""" namespace = PolarisNamespace(**self.properties) request = CreateNamespaceRequest() - request.id = [] + request.id = ["only_catalog"] # Missing namespace level with self.assertRaises(InvalidInputException): namespace.create_namespace(request) diff --git a/python/tests/test_polaris_integration.py b/python/tests/test_polaris_integration.py new file mode 100644 index 0000000..d266903 --- /dev/null +++ b/python/tests/test_polaris_integration.py @@ -0,0 +1,228 @@ +""" +Integration tests for Polaris Catalog namespace implementation. + +To run these tests, start Polaris with: + cd docker/polaris && docker-compose up -d + +Tests are automatically skipped if Polaris is not available. +""" + +import os +import uuid +import urllib.request +import urllib.error +import unittest + +import pytest + +from lance_namespace_impls.polaris import PolarisNamespace +from lance_namespace_impls.rest_client import ( + NamespaceNotFoundException, + TableNotFoundException, +) +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateNamespaceRequest, + DeregisterTableRequest, + DescribeNamespaceRequest, + DescribeTableRequest, + DropNamespaceRequest, + ListNamespacesRequest, + ListTablesRequest, + NamespaceExistsRequest, + TableExistsRequest, +) + + +POLARIS_ENDPOINT = os.environ.get("POLARIS_ENDPOINT", "http://localhost:8181") +CLIENT_ID = os.environ.get("POLARIS_CLIENT_ID", "root") +CLIENT_SECRET = os.environ.get("POLARIS_CLIENT_SECRET", "s3cr3t") + + +def check_polaris_available(): + """Check if Polaris is available.""" + try: + url = f"{POLARIS_ENDPOINT}/api/catalog/v1/test_catalog/namespaces" + req = urllib.request.Request(url, method="GET") + try: + with urllib.request.urlopen(req, timeout=2) as response: + return response.status != 404 + except urllib.error.HTTPError as e: + # 401/403 means server is up but needs auth, 404 means not found + return e.code != 404 and e.code > 0 + except Exception: + return False + + +def get_oauth_token(): + """Get OAuth token from Polaris.""" + try: + url = f"{POLARIS_ENDPOINT}/api/catalog/v1/oauth/tokens" + data = f"grant_type=client_credentials&client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&scope=PRINCIPAL_ROLE:ALL" + req = urllib.request.Request( + url, + data=data.encode("utf-8"), + headers={"Content-Type": "application/x-www-form-urlencoded"}, + method="POST", + ) + with urllib.request.urlopen(req, timeout=5) as response: + import json + + body = response.read().decode("utf-8") + token_data = json.loads(body) + return token_data.get("access_token") + except Exception as e: + print(f"Failed to get OAuth token: {e}") + return None + + +polaris_available = check_polaris_available() + + +@pytest.mark.integration +@unittest.skipUnless( + polaris_available, f"Polaris is not available at {POLARIS_ENDPOINT}" +) +class TestPolarisNamespaceIntegration(unittest.TestCase): + """Integration tests for PolarisNamespace against a running Polaris instance.""" + + @classmethod + def setUpClass(cls): + """Set up class-level resources.""" + cls.token = get_oauth_token() + if not cls.token: + raise unittest.SkipTest("Failed to get OAuth token from Polaris") + + def setUp(self): + """Set up test fixtures.""" + unique_id = uuid.uuid4().hex[:8] + self.test_catalog = "test_catalog" + self.test_namespace = f"test_ns_{unique_id}" + + properties = { + "polaris.endpoint": POLARIS_ENDPOINT, + "polaris.auth_token": self.token, + "polaris.root": "/data/warehouse", + } + + self.namespace = PolarisNamespace(**properties) + + def tearDown(self): + """Clean up test resources.""" + try: + # Drop test namespace if it exists + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_catalog, self.test_namespace] + self.namespace.drop_namespace(drop_request) + except Exception: + pass + + if self.namespace: + self.namespace.close() + + def test_namespace_operations(self): + """Test namespace CRUD operations.""" + # Create namespace + create_request = CreateNamespaceRequest() + create_request.id = [self.test_catalog, self.test_namespace] + create_request.properties = {"description": "Test namespace"} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + # Describe namespace + describe_request = DescribeNamespaceRequest() + describe_request.id = [self.test_catalog, self.test_namespace] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + + # Check namespace exists + exists_request = NamespaceExistsRequest() + exists_request.id = [self.test_catalog, self.test_namespace] + self.namespace.namespace_exists(exists_request) # Should not throw + + # List namespaces + list_request = ListNamespacesRequest() + list_request.id = [self.test_catalog] + list_response = self.namespace.list_namespaces(list_request) + full_ns_name = f"{self.test_catalog}.{self.test_namespace}" + self.assertIn(full_ns_name, list_response.namespaces) + + # Drop namespace + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_catalog, self.test_namespace] + self.namespace.drop_namespace(drop_request) + + # Verify namespace doesn't exist + with self.assertRaises(NamespaceNotFoundException): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_catalog, self.test_namespace] + self.namespace.create_namespace(ns_request) + + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + + # Create empty table + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_catalog, self.test_namespace, table_name] + create_request.location = f"/data/warehouse/{self.test_namespace}/{table_name}" + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + + # Describe table + describe_request = DescribeTableRequest() + describe_request.id = [self.test_catalog, self.test_namespace, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + + # Check table exists + exists_request = TableExistsRequest() + exists_request.id = [self.test_catalog, self.test_namespace, table_name] + self.namespace.table_exists(exists_request) # Should not throw + + # List tables + list_request = ListTablesRequest() + list_request.id = [self.test_catalog, self.test_namespace] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + # Deregister table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_catalog, self.test_namespace, table_name] + self.namespace.deregister_table(deregister_request) + + # Verify table doesn't exist + with self.assertRaises(TableNotFoundException): + self.namespace.table_exists(exists_request) + + def test_create_empty_table_with_location(self): + """Test creating an empty table with a specific location.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_catalog, self.test_namespace] + self.namespace.create_namespace(ns_request) + + table_name = "lance_table" + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_catalog, self.test_namespace, table_name] + create_request.location = f"/data/warehouse/{self.test_namespace}/{table_name}" + + response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(response.location) + + # Clean up table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_catalog, self.test_namespace, table_name] + self.namespace.deregister_table(deregister_request) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/uv.lock b/python/uv.lock index 6a2cd24..7a79178 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -264,7 +264,7 @@ requires-dist = [ { name = "thrift", marker = "extra == 'hive3'", specifier = ">=0.13.0" }, { name = "typing-extensions", specifier = ">=4.5.0" }, ] -provides-extras = ["glue", "hive2", "hive3", "unity", "all", "dev"] +provides-extras = ["glue", "hive2", "hive3", "unity", "polaris", "all", "dev"] [[package]] name = "lance-namespace-urllib3-client" From 63b6a18dcc53482e3ccee624381c4cd4551b91bd Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 18:09:53 -0800 Subject: [PATCH 04/20] fix unity --- .github/workflows/python-integ-unity.yml | 4 + docs/src/unity.md | 71 ++-- python/Makefile | 6 +- .../src/lance_namespace_impls/rest_client.py | 12 +- python/src/lance_namespace_impls/unity.py | 136 ++++---- python/tests/test_unity.py | 313 ++++++++++-------- python/tests/test_unity_integration.py | 227 +++++++++++++ 7 files changed, 501 insertions(+), 268 deletions(-) create mode 100644 python/tests/test_unity_integration.py diff --git a/.github/workflows/python-integ-unity.yml b/.github/workflows/python-integ-unity.yml index 36b7b0b..6b59c96 100644 --- a/.github/workflows/python-integ-unity.yml +++ b/.github/workflows/python-integ-unity.yml @@ -18,7 +18,9 @@ on: - main paths: - python/src/lance_namespace_impls/unity.py + - python/src/lance_namespace_impls/rest_client.py - python/tests/test_unity.py + - python/tests/test_unity_integration.py - docker/unity/** - .github/workflows/python-integ-unity.yml pull_request: @@ -29,7 +31,9 @@ on: - reopened paths: - python/src/lance_namespace_impls/unity.py + - python/src/lance_namespace_impls/rest_client.py - python/tests/test_unity.py + - python/tests/test_unity_integration.py - docker/unity/** - .github/workflows/python-integ-unity.yml workflow_dispatch: diff --git a/docs/src/unity.md b/docs/src/unity.md index 3ec97b5..161038d 100644 --- a/docs/src/unity.md +++ b/docs/src/unity.md @@ -12,31 +12,25 @@ The Lance Unity namespace implementation accepts the following configuration pro The **endpoint** property is required and specifies the Unity Catalog REST API endpoint (e.g., `http://localhost:8080`). -The **catalog** property is required and specifies the Unity Catalog name to use. - -The **api_path** property is optional and specifies the API path prefix. Default value is `/api/2.1/unity-catalog`. - The **auth_token** property is optional and specifies the bearer token for authentication. -The **connect_timeout** property is optional and specifies the HTTP connection timeout in seconds. Default value is `10`. +The **connect_timeout** property is optional and specifies the HTTP connection timeout in milliseconds. Default value is `10000` (10 seconds). -The **read_timeout** property is optional and specifies the HTTP read timeout in seconds. Default value is `60`. +The **read_timeout** property is optional and specifies the HTTP read timeout in milliseconds. Default value is `300000` (5 minutes). The **max_retries** property is optional and specifies the maximum number of retries for failed requests. Default value is `3`. -The **root** property is optional and specifies the storage root location of the lakehouse. Default value is the current working directory. - -The **storage.*** prefix properties are optional and specify additional storage configurations to access tables (e.g., `storage.region=us-west-2`). +The **root** property is optional and specifies the storage root location for new tables. Default value is `/tmp/lance`. ## Object Mapping ### Namespace -The **root namespace** is represented by the configured Unity Catalog. The catalog name is fixed at initialization time. +The **namespace identifier** follows a hierarchical structure where the first level represents the Unity Catalog, and the second level represents a schema within that catalog. For example, `my_catalog.my_schema` refers to schema `my_schema` in catalog `my_catalog`. -A **child namespace** is a schema within the Unity Catalog. Unity supports a fixed 3-level hierarchy: catalog.schema.table. +The **root namespace** (empty identifier) lists all available catalogs in the Unity Catalog server. -The **namespace identifier** is constructed by joining the catalog and schema names with the `$` delimiter (e.g., `catalog$schema`). The first level is always the configured catalog. +A **child namespace** is a schema within a Unity Catalog. Unity supports a fixed 3-level hierarchy: catalog.schema.table. **Namespace properties** are stored in the Unity schema's properties map. @@ -44,7 +38,7 @@ The **namespace identifier** is constructed by joining the catalog and schema na A **table** is represented as a [Table](https://github.com/unitycatalog/unitycatalog/blob/main/api/all.yaml) object in Unity Catalog with `table_type` set to `EXTERNAL`. -The **table identifier** is constructed by joining catalog, schema, and table name with the `$` delimiter (e.g., `catalog$schema$table`). +The **table identifier** is constructed by joining catalog, schema, and table name (e.g., `catalog.schema.table`). The **table location** is stored in the `storage_location` field of the Unity Table, pointing to the root location of the Lance table. @@ -65,29 +59,28 @@ Creates a new schema in Unity Catalog. The implementation: 1. Parse the namespace identifier (must be 2-level: catalog.schema) -2. Verify the catalog matches the configured catalog -3. Construct a CreateSchema request with name, catalog name, and properties -4. POST to `/schemas` endpoint -5. Return the created schema properties +2. Construct a CreateSchema request with name, catalog name, and properties +3. POST to `/schemas` endpoint +4. Return the created schema properties **Error Handling:** -If the catalog does not match the configured catalog, return error code `13` (InvalidInput). If the schema already exists, return error code `2` (NamespaceAlreadyExists). If the server returns an error, return error code `18` (Internal). +If the schema already exists, return error code `2` (NamespaceAlreadyExists). If the server returns an error, return error code `18` (Internal). ### ListNamespaces -Lists schemas in the Unity Catalog. +Lists catalogs or schemas in the Unity Catalog. The implementation: 1. Parse the parent namespace identifier -2. For root namespace (level 0): return the configured catalog name -3. For catalog namespace (level 1): GET `/schemas` with catalog_name parameter +2. For root namespace (level 0): GET `/catalogs` to list all available catalogs +3. For catalog namespace (level 1): GET `/schemas` with catalog_name parameter to list schemas 4. Sort the results **Error Handling:** -If the catalog does not match the configured catalog, return error code `1` (NamespaceNotFound). If the server returns an error, return error code `18` (Internal). +If the catalog does not exist, return error code `1` (NamespaceNotFound). If the server returns an error, return error code `18` (Internal). ### DescribeNamespace @@ -96,9 +89,8 @@ Retrieves properties and metadata for a schema. The implementation: 1. Parse the namespace identifier (must be 2-level: catalog.schema) -2. Verify the catalog matches the configured catalog -3. GET `/schemas/{catalog}.{schema}` -4. Return the schema properties +2. GET `/schemas/{catalog}.{schema}` +3. Return the schema properties **Error Handling:** @@ -111,8 +103,7 @@ Removes a schema from Unity Catalog. Only RESTRICT mode is supported; CASCADE mo The implementation: 1. Parse the namespace identifier (must be 2-level: catalog.schema) -2. Verify the catalog matches the configured catalog -3. DELETE `/schemas/{catalog}.{schema}` +2. DELETE `/schemas/{catalog}.{schema}` **Error Handling:** @@ -129,8 +120,7 @@ Declares a new Lance table in Unity Catalog without creating the underlying data The implementation: 1. Parse the table identifier (must be 3-level: catalog.schema.table) -2. Verify the catalog matches the configured catalog -3. Construct a CreateTable request with: +2. Construct a CreateTable request with: - `name`: the table name - `catalog_name`: the catalog - `schema_name`: the schema @@ -138,8 +128,8 @@ The implementation: - `data_source_format`: `TEXT` - `storage_location`: the specified or default location - `properties`: including `table_type=lance` -4. POST to `/tables` endpoint -5. Return the created table location and properties +3. POST to `/tables` endpoint +4. Return the created table location and properties **Error Handling:** @@ -152,10 +142,9 @@ Lists all Lance tables in a schema. The implementation: 1. Parse the namespace identifier (must be 2-level: catalog.schema) -2. Verify the catalog matches the configured catalog -3. GET `/tables` with catalog_name and schema_name parameters -4. Filter tables where `properties.table_type=lance` -5. Sort the results +2. GET `/tables` with catalog_name and schema_name parameters +3. Filter tables where `properties.table_type=lance` +4. Sort the results **Error Handling:** @@ -168,10 +157,9 @@ Retrieves metadata for a Lance table. Only `load_detailed_metadata=false` is sup The implementation: 1. Parse the table identifier (must be 3-level: catalog.schema.table) -2. Verify the catalog matches the configured catalog -3. GET `/tables/{catalog}.{schema}.{table}` -4. Verify the table is a Lance table (check `properties.table_type=lance`) -5. Return the table location from `storage_location` and storage_options from `properties` +2. GET `/tables/{catalog}.{schema}.{table}` +3. Verify the table is a Lance table (check `properties.table_type=lance`) +4. Return the table location from `storage_location` and storage_options from `properties` **Error Handling:** @@ -188,9 +176,8 @@ Removes a Lance table registration from Unity Catalog without deleting the under The implementation: 1. Parse the table identifier (must be 3-level: catalog.schema.table) -2. Verify the catalog matches the configured catalog -3. GET the table and verify it is a Lance table -4. DELETE `/tables/{catalog}.{schema}.{table}` +2. GET the table and verify it is a Lance table +3. DELETE `/tables/{catalog}.{schema}.{table}` **Error Handling:** diff --git a/python/Makefile b/python/Makefile index f4890dd..974c606 100644 --- a/python/Makefile +++ b/python/Makefile @@ -50,8 +50,8 @@ test-hive: .PHONY: lint-unity lint-unity: - uv run ruff check src/lance_namespace_impls/unity.py tests/test_unity.py - uv run ruff format --check src/lance_namespace_impls/unity.py tests/test_unity.py + uv run ruff check src/lance_namespace_impls/unity.py tests/test_unity.py tests/test_unity_integration.py + uv run ruff format --check src/lance_namespace_impls/unity.py tests/test_unity.py tests/test_unity_integration.py .PHONY: install-unity install-unity: @@ -147,4 +147,4 @@ integ-test-polaris: .PHONY: integ-test-unity integ-test-unity: - uv run pytest tests/test_unity.py -m integration + uv run pytest tests/test_unity_integration.py -v diff --git a/python/src/lance_namespace_impls/rest_client.py b/python/src/lance_namespace_impls/rest_client.py index 604bd1f..9909579 100644 --- a/python/src/lance_namespace_impls/rest_client.py +++ b/python/src/lance_namespace_impls/rest_client.py @@ -121,7 +121,17 @@ def _make_request( raise RestClientException(response.status, response.data.decode("utf-8")) if response.data: - return json.loads(response.data.decode("utf-8")) + data = response.data.decode("utf-8") + # Handle empty or non-JSON responses (e.g., "200 OK" for DELETE) + if not data or data.strip() in ("", "200 OK", "OK"): + return None + try: + return json.loads(data) + except json.JSONDecodeError: + # If it's not valid JSON, return None for successful responses + if response.status < 300: + return None + raise return None except urllib3.exceptions.HTTPError as e: diff --git a/python/src/lance_namespace_impls/unity.py b/python/src/lance_namespace_impls/unity.py index 2cf0629..8929a28 100644 --- a/python/src/lance_namespace_impls/unity.py +++ b/python/src/lance_namespace_impls/unity.py @@ -4,12 +4,9 @@ import io import logging -import os -import shutil from dataclasses import dataclass, field from typing import Any, Dict, List, Optional -import lance import pyarrow as pa import pyarrow.ipc as ipc @@ -58,7 +55,6 @@ class UnityNamespaceConfig: """Configuration for Unity Catalog namespace.""" ENDPOINT = "unity.endpoint" - CATALOG = "unity.catalog" ROOT = "unity.root" AUTH_TOKEN = "unity.auth_token" CONNECT_TIMEOUT = "unity.connect_timeout_millis" @@ -66,7 +62,6 @@ class UnityNamespaceConfig: MAX_RETRIES = "unity.max_retries" endpoint: str - catalog: str root: str auth_token: Optional[str] = None connect_timeout: int = 10000 @@ -78,7 +73,6 @@ def __init__(self, properties: Dict[str, str]): if not self.endpoint: raise ValueError(f"Required property {self.ENDPOINT} is not set") - self.catalog = properties.get(self.CATALOG, "unity") self.root = properties.get(self.ROOT, "/tmp/lance") self.auth_token = properties.get(self.AUTH_TOKEN) self.connect_timeout = int(properties.get(self.CONNECT_TIMEOUT, "10000")) @@ -86,10 +80,13 @@ def __init__(self, properties: Dict[str, str]): self.max_retries = int(properties.get(self.MAX_RETRIES, "3")) def get_full_api_url(self) -> str: - """Get the full API URL with /api/2.1 path.""" + """Get the full API URL with /api/2.1/unity-catalog path.""" base = self.endpoint.rstrip("/") - if not base.endswith("/api/2.1"): - base = f"{base}/api/2.1" + if not base.endswith("/api/2.1/unity-catalog"): + if base.endswith("/api/2.1"): + base = f"{base}/unity-catalog" + else: + base = f"{base}/api/2.1/unity-catalog" return base @@ -226,32 +223,44 @@ def __init__(self, **properties): max_retries=self.config.max_retries, ) - logger.info(f"Initialized Unity namespace with endpoint: {self.config.endpoint}") + logger.info( + f"Initialized Unity namespace with endpoint: {self.config.endpoint}" + ) def namespace_id(self) -> str: """Return a human-readable unique identifier for this namespace instance.""" - return f"UnityNamespace {{ endpoint: {self.config.endpoint!r}, catalog: {self.config.catalog!r} }}" + return f"UnityNamespace {{ endpoint: {self.config.endpoint!r} }}" def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: """List namespaces.""" ns_id = self._parse_identifier(request.id) - if len(ns_id) > 2: + if len(ns_id) > 1: raise InvalidInputException( - f"Expect at most 2-level namespace but get {'.'.join(ns_id)}" + f"Expect at most 1-level namespace but get {'.'.join(ns_id)}" ) try: namespaces = [] if len(ns_id) == 0: - namespaces = [self.config.catalog] + # List all catalogs + params = {} + if request.limit: + params["max_results"] = str(request.limit) + if request.page_token: + params["page_token"] = request.page_token + + response = self.rest_client.get( + "/catalogs", params=params if params else None + ) + + if response and "catalogs" in response: + namespaces = [catalog["name"] for catalog in response["catalogs"]] + elif len(ns_id) == 1: + # List schemas in a catalog catalog = ns_id[0] - if catalog != self.config.catalog: - raise NamespaceNotFoundException( - f"Catalog not found: {catalog}, expected: {self.config.catalog}" - ) params = {"catalog_name": catalog} if request.limit: @@ -268,28 +277,31 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo return ListNamespacesResponse(namespaces=namespaces) - except (NamespaceNotFoundException, InvalidInputException): + except RestClientException as e: + if e.is_not_found(): + raise NamespaceNotFoundException( + f"Namespace not found: {'.'.join(ns_id)}" + ) + raise InternalException(f"Failed to list namespaces: {e}") + except InvalidInputException: raise except Exception as e: raise InternalException(f"Failed to list namespaces: {e}") - def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: """Create a new namespace.""" ns_id = self._parse_identifier(request.id) if len(ns_id) != 2: raise InvalidInputException( - f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + f"Expect a 2-level namespace (catalog.schema) but get {'.'.join(ns_id)}" ) catalog = ns_id[0] schema = ns_id[1] - if catalog != self.config.catalog: - raise InvalidInputException( - f"Cannot create namespace in catalog {catalog}, expected: {self.config.catalog}" - ) - try: create_schema = CreateSchema( name=schema, catalog_name=catalog, properties=request.properties @@ -322,17 +334,12 @@ def describe_namespace( if len(ns_id) != 2: raise InvalidInputException( - f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + f"Expect a 2-level namespace (catalog.schema) but get {'.'.join(ns_id)}" ) catalog = ns_id[0] schema = ns_id[1] - if catalog != self.config.catalog: - raise NamespaceNotFoundException( - f"Catalog not found: {catalog}, expected: {self.config.catalog}" - ) - try: full_name = f"{catalog}.{schema}" schema_info = self.rest_client.get( @@ -364,17 +371,12 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse if len(ns_id) != 2: raise InvalidInputException( - f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + f"Expect a 2-level namespace (catalog.schema) but get {'.'.join(ns_id)}" ) catalog = ns_id[0] schema = ns_id[1] - if catalog != self.config.catalog: - raise InvalidInputException( - f"Cannot drop namespace in catalog {catalog}, expected: {self.config.catalog}" - ) - try: full_name = f"{catalog}.{schema}" self.rest_client.delete(f"/schemas/{full_name}") @@ -397,17 +399,12 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: if len(ns_id) != 2: raise InvalidInputException( - f"Expect a 2-level namespace but get {'.'.join(ns_id)}" + f"Expect a 2-level namespace (catalog.schema) but get {'.'.join(ns_id)}" ) catalog = ns_id[0] schema = ns_id[1] - if catalog != self.config.catalog: - raise NamespaceNotFoundException( - f"Catalog not found: {catalog}, expected: {self.config.catalog}" - ) - try: params = {"catalog_name": catalog, "schema_name": schema} if request.limit: @@ -453,18 +450,13 @@ def create_empty_table( if len(table_id) != 3: raise InvalidInputException( - f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + f"Expect a 3-level table identifier (catalog.schema.table) but get {'.'.join(table_id)}" ) catalog = table_id[0] schema = table_id[1] table = table_id[2] - if catalog != self.config.catalog: - raise InvalidInputException( - f"Cannot create empty table in catalog {catalog}, expected: {self.config.catalog}" - ) - try: table_path = request.location if not table_path: @@ -473,9 +465,9 @@ def create_empty_table( columns = [ ColumnInfo( name="__placeholder_id", - type_text="BIGINT", + type_text="LONG", type_json='{"type":"long"}', - type_name="BIGINT", + type_name="LONG", position=0, nullable=True, ) @@ -497,7 +489,7 @@ def create_empty_table( properties=properties, ) - table_info = self.rest_client.post( + self.rest_client.post( "/tables", create_table, response_converter=_parse_table_info ) @@ -522,18 +514,13 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse if len(table_id) != 3: raise InvalidInputException( - f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + f"Expect a 3-level table identifier (catalog.schema.table) but get {'.'.join(table_id)}" ) catalog = table_id[0] schema = table_id[1] table = table_id[2] - if catalog != self.config.catalog: - raise NamespaceNotFoundException( - f"Catalog not found: {catalog}, expected: {self.config.catalog}" - ) - try: full_name = f"{catalog}.{schema}.{table}" table_info = self.rest_client.get( @@ -547,14 +534,12 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse return DescribeTableResponse( location=table_info.storage_location, - storage_options=table_info.properties + storage_options=table_info.properties, ) except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to describe table: {e}") except Exception as e: if isinstance( @@ -593,18 +578,13 @@ def deregister_table( if len(table_id) != 3: raise InvalidInputException( - f"Expect a 3-level table identifier but get {'.'.join(table_id)}" + f"Expect a 3-level table identifier (catalog.schema.table) but get {'.'.join(table_id)}" ) catalog = table_id[0] schema = table_id[1] table = table_id[2] - if catalog != self.config.catalog: - raise InvalidInputException( - f"Cannot deregister table in catalog {catalog}, expected: {self.config.catalog}" - ) - try: full_name = f"{catalog}.{schema}.{table}" @@ -626,9 +606,7 @@ def deregister_table( except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to deregister table: {e}") except Exception as e: if isinstance(e, (TableNotFoundException, InvalidInputException)): @@ -672,17 +650,19 @@ def _convert_arrow_schema_to_unity_columns( ) -> List[ColumnInfo]: """Convert Arrow schema to Unity column definitions.""" columns = [] - for i, field in enumerate(arrow_schema): - unity_type = self._convert_arrow_type_to_unity_type(field.type) - unity_type_json = self._convert_arrow_type_to_unity_type_json(field.type) + for i, arrow_field in enumerate(arrow_schema): + unity_type = self._convert_arrow_type_to_unity_type(arrow_field.type) + unity_type_json = self._convert_arrow_type_to_unity_type_json( + arrow_field.type + ) column = ColumnInfo( - name=field.name, + name=arrow_field.name, type_text=unity_type, type_json=unity_type_json, type_name=unity_type, position=i, - nullable=field.nullable, + nullable=arrow_field.nullable, ) columns.append(column) @@ -695,7 +675,7 @@ def _convert_arrow_type_to_unity_type(self, arrow_type: pa.DataType) -> str: elif pa.types.is_int32(arrow_type): return "INT" elif pa.types.is_int64(arrow_type): - return "BIGINT" + return "LONG" elif pa.types.is_float32(arrow_type): return "FLOAT" elif pa.types.is_float64(arrow_type): diff --git a/python/tests/test_unity.py b/python/tests/test_unity.py index ab159f4..3057679 100644 --- a/python/tests/test_unity.py +++ b/python/tests/test_unity.py @@ -3,30 +3,19 @@ """ import unittest -from unittest.mock import Mock, patch, MagicMock -import json -import io +from unittest.mock import patch, MagicMock import pyarrow as pa -import pyarrow.ipc as ipc from lance_namespace_impls.unity import ( UnityNamespace, UnityNamespaceConfig, SchemaInfo, TableInfo, - ColumnInfo, ) from lance_namespace_impls.rest_client import ( RestClient, RestClientException, - NamespaceException, - NamespaceNotFoundException, - NamespaceAlreadyExistsException, - TableNotFoundException, - TableAlreadyExistsException, - InvalidInputException, - InternalException, ) from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, @@ -43,69 +32,74 @@ class TestUnityNamespaceConfig(unittest.TestCase): """Test Unity namespace configuration.""" - + def test_config_initialization(self): """Test configuration initialization with required properties.""" properties = { "unity.endpoint": "https://unity.example.com", - "unity.catalog": "test_catalog", "unity.root": "/data/lance", - "unity.auth_token": "test_token" + "unity.auth_token": "test_token", } - + config = UnityNamespaceConfig(properties) - + self.assertEqual(config.endpoint, "https://unity.example.com") - self.assertEqual(config.catalog, "test_catalog") self.assertEqual(config.root, "/data/lance") self.assertEqual(config.auth_token, "test_token") - + def test_config_defaults(self): """Test configuration with default values.""" - properties = { - "unity.endpoint": "https://unity.example.com" - } - + properties = {"unity.endpoint": "https://unity.example.com"} + config = UnityNamespaceConfig(properties) - - self.assertEqual(config.catalog, "unity") + self.assertEqual(config.root, "/tmp/lance") self.assertIsNone(config.auth_token) self.assertEqual(config.connect_timeout, 10000) self.assertEqual(config.read_timeout, 300000) self.assertEqual(config.max_retries, 3) - + def test_config_missing_endpoint(self): """Test configuration fails without endpoint.""" properties = {} - + with self.assertRaises(ValueError) as context: UnityNamespaceConfig(properties) - + self.assertIn("unity.endpoint", str(context.exception)) - + def test_get_full_api_url(self): """Test API URL generation.""" - properties = { - "unity.endpoint": "https://unity.example.com" - } + properties = {"unity.endpoint": "https://unity.example.com"} config = UnityNamespaceConfig(properties) - - self.assertEqual(config.get_full_api_url(), "https://unity.example.com/api/2.1") - + + self.assertEqual( + config.get_full_api_url(), "https://unity.example.com/api/2.1/unity-catalog" + ) + # Test with endpoint already containing /api/2.1 + properties = {"unity.endpoint": "https://unity.example.com/api/2.1"} + config = UnityNamespaceConfig(properties) + + self.assertEqual( + config.get_full_api_url(), "https://unity.example.com/api/2.1/unity-catalog" + ) + + # Test with endpoint already containing full path properties = { - "unity.endpoint": "https://unity.example.com/api/2.1" + "unity.endpoint": "https://unity.example.com/api/2.1/unity-catalog" } config = UnityNamespaceConfig(properties) - - self.assertEqual(config.get_full_api_url(), "https://unity.example.com/api/2.1") + + self.assertEqual( + config.get_full_api_url(), "https://unity.example.com/api/2.1/unity-catalog" + ) class TestRestClient(unittest.TestCase): """Test REST client functionality.""" - - @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') + + @patch("lance_namespace_impls.rest_client.urllib3.PoolManager") def test_get_request(self, mock_pool_manager): """Test GET request.""" mock_http = MagicMock() @@ -122,7 +116,7 @@ def test_get_request(self, mock_pool_manager): self.assertEqual(result, {"name": "test_schema"}) mock_http.request.assert_called_once() - @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') + @patch("lance_namespace_impls.rest_client.urllib3.PoolManager") def test_post_request(self, mock_pool_manager): """Test POST request.""" mock_http = MagicMock() @@ -139,7 +133,7 @@ def test_post_request(self, mock_pool_manager): self.assertEqual(result, {"id": "123"}) mock_http.request.assert_called_once() - @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') + @patch("lance_namespace_impls.rest_client.urllib3.PoolManager") def test_delete_request(self, mock_pool_manager): """Test DELETE request.""" mock_http = MagicMock() @@ -147,7 +141,7 @@ def test_delete_request(self, mock_pool_manager): mock_response = MagicMock() mock_response.status = 204 - mock_response.data = b'' + mock_response.data = b"" mock_http.request.return_value = mock_response client = RestClient("https://api.example.com") @@ -155,7 +149,7 @@ def test_delete_request(self, mock_pool_manager): mock_http.request.assert_called_once() - @patch('lance_namespace_impls.rest_client.urllib3.PoolManager') + @patch("lance_namespace_impls.rest_client.urllib3.PoolManager") def test_error_response(self, mock_pool_manager): """Test error response handling.""" mock_http = MagicMock() @@ -177,90 +171,85 @@ def test_error_response(self, mock_pool_manager): class TestUnityNamespace(unittest.TestCase): """Test Unity namespace implementation.""" - + def setUp(self): """Set up test fixtures.""" self.properties = { "unity.endpoint": "https://unity.example.com", - "unity.catalog": "test_catalog", - "unity.root": "/data/lance" + "unity.root": "/data/lance", } - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_list_namespaces_top_level(self, mock_rest_client_class): """Test listing top-level namespaces (catalogs).""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + + mock_client.get.return_value = { + "catalogs": [{"name": "catalog1"}, {"name": "catalog2"}] + } + namespace = UnityNamespace(**self.properties) - + request = ListNamespacesRequest() request.id = [] - + response = namespace.list_namespaces(request) - - self.assertEqual(response.namespaces, ["test_catalog"]) - mock_client.get.assert_not_called() - - @patch('lance_namespace_impls.unity.RestClient') + + self.assertEqual(sorted(response.namespaces), ["catalog1", "catalog2"]) + mock_client.get.assert_called_once_with("/catalogs", params=None) + + @patch("lance_namespace_impls.unity.RestClient") def test_list_namespaces_schemas(self, mock_rest_client_class): """Test listing schemas in a catalog.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_client.get.return_value = { - "schemas": [ - {"name": "schema1"}, - {"name": "schema2"} - ] + "schemas": [{"name": "schema1"}, {"name": "schema2"}] } - + namespace = UnityNamespace(**self.properties) - + request = ListNamespacesRequest() request.id = ["test_catalog"] - + response = namespace.list_namespaces(request) - + self.assertEqual(sorted(response.namespaces), ["schema1", "schema2"]) mock_client.get.assert_called_once_with( - '/schemas', - params={'catalog_name': 'test_catalog'} + "/schemas", params={"catalog_name": "test_catalog"} ) - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_create_namespace(self, mock_rest_client_class): """Test creating a namespace.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_schema_info = SchemaInfo( - name="test_schema", - catalog_name="test_catalog", - properties={"key": "value"} + name="test_schema", catalog_name="test_catalog", properties={"key": "value"} ) mock_client.post.return_value = mock_schema_info - + namespace = UnityNamespace(**self.properties) - + request = CreateNamespaceRequest() request.id = ["test_catalog", "test_schema"] request.properties = {"key": "value"} - + response = namespace.create_namespace(request) - + self.assertEqual(response.properties, {"key": "value"}) - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_describe_namespace(self, mock_rest_client_class): """Test describing a namespace.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client mock_schema_info = SchemaInfo( - name="test_schema", - catalog_name="test_catalog", - properties={"key": "value"} + name="test_schema", catalog_name="test_catalog", properties={"key": "value"} ) mock_client.get.return_value = mock_schema_info @@ -273,8 +262,8 @@ def test_describe_namespace(self, mock_rest_client_class): self.assertEqual(response.properties, {"key": "value"}) mock_client.get.assert_called_once() - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_drop_namespace(self, mock_rest_client_class): """Test dropping a namespace.""" mock_client = MagicMock() @@ -289,32 +278,32 @@ def test_drop_namespace(self, mock_rest_client_class): self.assertIsNotNone(response) mock_client.delete.assert_called_once() - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_list_tables(self, mock_rest_client_class): """Test listing tables in a namespace.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_client.get.return_value = { "tables": [ {"name": "table1", "properties": {"table_type": "lance"}}, {"name": "table2", "properties": {"table_type": "delta"}}, - {"name": "table3", "properties": {"table_type": "lance"}} + {"name": "table3", "properties": {"table_type": "lance"}}, ] } - + namespace = UnityNamespace(**self.properties) - + request = ListTablesRequest() request.id = ["test_catalog", "test_schema"] - + response = namespace.list_tables(request) - + # Should only return Lance tables self.assertEqual(sorted(response.tables), ["table1", "table3"]) - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_create_table_not_supported(self, mock_rest_client_class): """Test that create_table raises NotImplementedError.""" mock_client = MagicMock() @@ -329,13 +318,13 @@ def test_create_table_not_supported(self, mock_rest_client_class): namespace.create_table(request, b"test_data") self.assertIn("create_table is not supported", str(context.exception)) - - @patch('lance_namespace_impls.unity.RestClient') + + @patch("lance_namespace_impls.unity.RestClient") def test_create_empty_table(self, mock_rest_client_class): """Test creating an empty table.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_table_info = TableInfo( name="test_table", catalog_name="test_catalog", @@ -344,26 +333,27 @@ def test_create_empty_table(self, mock_rest_client_class): data_source_format="TEXT", columns=[], storage_location="/data/lance/test_catalog/test_schema/test_table", - properties={"table_type": "lance"} + properties={"table_type": "lance"}, ) mock_client.post.return_value = mock_table_info - + namespace = UnityNamespace(**self.properties) - + request = CreateEmptyTableRequest() request.id = ["test_catalog", "test_schema", "test_table"] - + response = namespace.create_empty_table(request) - - self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - - @patch('lance_namespace_impls.unity.lance') - @patch('lance_namespace_impls.unity.RestClient') - def test_describe_table(self, mock_rest_client_class, mock_lance): + + self.assertEqual( + response.location, "/data/lance/test_catalog/test_schema/test_table" + ) + + @patch("lance_namespace_impls.unity.RestClient") + def test_describe_table(self, mock_rest_client_class): """Test describing a table.""" mock_client = MagicMock() mock_rest_client_class.return_value = mock_client - + mock_table_info = TableInfo( name="test_table", catalog_name="test_catalog", @@ -372,25 +362,22 @@ def test_describe_table(self, mock_rest_client_class, mock_lance): data_source_format="TEXT", columns=[], storage_location="/data/lance/test_catalog/test_schema/test_table", - properties={"table_type": "lance"} + properties={"table_type": "lance"}, ) mock_client.get.return_value = mock_table_info - - # Mock Lance dataset - mock_dataset = MagicMock() - mock_dataset.schema = pa.schema([pa.field("id", pa.int64())]) - mock_lance.dataset.return_value = mock_dataset - + namespace = UnityNamespace(**self.properties) - + request = DescribeTableRequest() request.id = ["test_catalog", "test_schema", "test_table"] - + response = namespace.describe_table(request) - self.assertEqual(response.location, "/data/lance/test_catalog/test_schema/test_table") - - @patch('lance_namespace_impls.unity.RestClient') + self.assertEqual( + response.location, "/data/lance/test_catalog/test_schema/test_table" + ) + + @patch("lance_namespace_impls.unity.RestClient") def test_drop_table_not_supported(self, mock_rest_client_class): """Test that drop_table raises NotImplementedError.""" mock_client = MagicMock() @@ -405,35 +392,73 @@ def test_drop_table_not_supported(self, mock_rest_client_class): namespace.drop_table(request) self.assertIn("drop_table is not supported", str(context.exception)) - + def test_arrow_type_conversion(self): """Test Arrow type to Unity type conversion.""" namespace = UnityNamespace(**self.properties) - + # Test various Arrow types - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.string()), "STRING") + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.string()), "STRING" + ) self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.int32()), "INT") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.int64()), "BIGINT") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.float32()), "FLOAT") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.float64()), "DOUBLE") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.bool_()), "BOOLEAN") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.date32()), "DATE") - self.assertEqual(namespace._convert_arrow_type_to_unity_type(pa.timestamp('us')), "TIMESTAMP") - + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.int64()), "LONG" + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.float32()), "FLOAT" + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.float64()), "DOUBLE" + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.bool_()), "BOOLEAN" + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.date32()), "DATE" + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type(pa.timestamp("us")), "TIMESTAMP" + ) + def test_arrow_type_to_json_conversion(self): """Test Arrow type to Unity JSON type conversion.""" namespace = UnityNamespace(**self.properties) - + # Test various Arrow types - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.string()), '{"type":"string"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.int32()), '{"type":"integer"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.int64()), '{"type":"long"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.float32()), '{"type":"float"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.float64()), '{"type":"double"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.bool_()), '{"type":"boolean"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.date32()), '{"type":"date"}') - self.assertEqual(namespace._convert_arrow_type_to_unity_type_json(pa.timestamp('us')), '{"type":"timestamp"}') - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.string()), + '{"type":"string"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.int32()), + '{"type":"integer"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.int64()), + '{"type":"long"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.float32()), + '{"type":"float"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.float64()), + '{"type":"double"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.bool_()), + '{"type":"boolean"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.date32()), + '{"type":"date"}', + ) + self.assertEqual( + namespace._convert_arrow_type_to_unity_type_json(pa.timestamp("us")), + '{"type":"timestamp"}', + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/tests/test_unity_integration.py b/python/tests/test_unity_integration.py new file mode 100644 index 0000000..0495be9 --- /dev/null +++ b/python/tests/test_unity_integration.py @@ -0,0 +1,227 @@ +""" +Integration tests for Unity Catalog namespace implementation. + +To run these tests, start Unity Catalog with: + cd docker/unity && docker-compose up -d + +Tests are automatically skipped if Unity Catalog is not available. +""" + +import os +import uuid +import urllib.request +import urllib.error +import unittest + +import pytest + +from lance_namespace_impls.unity import UnityNamespace +from lance_namespace_impls.rest_client import ( + NamespaceNotFoundException, + TableNotFoundException, +) +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateNamespaceRequest, + DeregisterTableRequest, + DescribeNamespaceRequest, + DescribeTableRequest, + DropNamespaceRequest, + ListNamespacesRequest, + ListTablesRequest, + NamespaceExistsRequest, + TableExistsRequest, +) + + +UNITY_ENDPOINT = os.environ.get("UNITY_ENDPOINT", "http://localhost:8080") +UNITY_CATALOG = os.environ.get("UNITY_CATALOG", "lance_test") + + +def check_unity_available(): + """Check if Unity Catalog is available.""" + try: + url = f"{UNITY_ENDPOINT}/api/2.1/unity-catalog/catalogs" + req = urllib.request.Request(url, method="GET") + try: + with urllib.request.urlopen(req, timeout=2) as response: + return response.status == 200 + except urllib.error.HTTPError as e: + return e.code != 404 and e.code > 0 + except Exception: + return False + + +def check_catalog_exists(): + """Check if the test catalog exists.""" + try: + url = f"{UNITY_ENDPOINT}/api/2.1/unity-catalog/catalogs/{UNITY_CATALOG}" + req = urllib.request.Request(url, method="GET") + with urllib.request.urlopen(req, timeout=2) as response: + return response.status == 200 + except Exception: + return False + + +unity_available = check_unity_available() + + +@pytest.mark.integration +@unittest.skipUnless( + unity_available, f"Unity Catalog is not available at {UNITY_ENDPOINT}" +) +class TestUnityNamespaceIntegration(unittest.TestCase): + """Integration tests for UnityNamespace against a running Unity Catalog instance.""" + + @classmethod + def setUpClass(cls): + """Set up class-level resources.""" + if not check_catalog_exists(): + raise unittest.SkipTest( + f"Test catalog '{UNITY_CATALOG}' does not exist in Unity Catalog" + ) + + def setUp(self): + """Set up test fixtures.""" + unique_id = uuid.uuid4().hex[:8] + self.test_schema = f"test_schema_{unique_id}" + + properties = { + "unity.endpoint": UNITY_ENDPOINT, + "unity.root": "/tmp/lance", + } + + self.namespace = UnityNamespace(**properties) + + def tearDown(self): + """Clean up test resources.""" + try: + # Drop test schema if it exists + drop_request = DropNamespaceRequest() + drop_request.id = [UNITY_CATALOG, self.test_schema] + self.namespace.drop_namespace(drop_request) + except Exception: + pass + + if self.namespace: + self.namespace.close() + + def test_list_catalogs(self): + """Test listing catalogs at root level.""" + list_request = ListNamespacesRequest() + list_request.id = [] + + response = self.namespace.list_namespaces(list_request) + + # Should list all catalogs including our test catalog + self.assertIn(UNITY_CATALOG, response.namespaces) + + def test_namespace_operations(self): + """Test namespace CRUD operations.""" + # Create namespace (schema) + create_request = CreateNamespaceRequest() + create_request.id = [UNITY_CATALOG, self.test_schema] + create_request.properties = {} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + # Describe namespace + describe_request = DescribeNamespaceRequest() + describe_request.id = [UNITY_CATALOG, self.test_schema] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + + # Check namespace exists + exists_request = NamespaceExistsRequest() + exists_request.id = [UNITY_CATALOG, self.test_schema] + self.namespace.namespace_exists(exists_request) # Should not throw + + # List namespaces (schemas) + list_request = ListNamespacesRequest() + list_request.id = [UNITY_CATALOG] + list_response = self.namespace.list_namespaces(list_request) + self.assertIn(self.test_schema, list_response.namespaces) + + # Drop namespace + drop_request = DropNamespaceRequest() + drop_request.id = [UNITY_CATALOG, self.test_schema] + self.namespace.drop_namespace(drop_request) + + # Verify namespace doesn't exist + with self.assertRaises(NamespaceNotFoundException): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [UNITY_CATALOG, self.test_schema] + self.namespace.create_namespace(ns_request) + + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + + # Create empty table + create_request = CreateEmptyTableRequest() + create_request.id = [UNITY_CATALOG, self.test_schema, table_name] + create_request.location = ( + f"/tmp/lance/{UNITY_CATALOG}/{self.test_schema}/{table_name}" + ) + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + + # Describe table + describe_request = DescribeTableRequest() + describe_request.id = [UNITY_CATALOG, self.test_schema, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + + # Check table exists + exists_request = TableExistsRequest() + exists_request.id = [UNITY_CATALOG, self.test_schema, table_name] + self.namespace.table_exists(exists_request) # Should not throw + + # List tables + list_request = ListTablesRequest() + list_request.id = [UNITY_CATALOG, self.test_schema] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + # Deregister table + deregister_request = DeregisterTableRequest() + deregister_request.id = [UNITY_CATALOG, self.test_schema, table_name] + self.namespace.deregister_table(deregister_request) + + # Verify table doesn't exist + with self.assertRaises(TableNotFoundException): + self.namespace.table_exists(exists_request) + + def test_create_empty_table_with_location(self): + """Test creating an empty table with a specific location.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [UNITY_CATALOG, self.test_schema] + self.namespace.create_namespace(ns_request) + + table_name = "lance_table" + create_request = CreateEmptyTableRequest() + create_request.id = [UNITY_CATALOG, self.test_schema, table_name] + create_request.location = ( + f"/tmp/lance/{UNITY_CATALOG}/{self.test_schema}/{table_name}" + ) + + response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(response.location) + + # Clean up table + deregister_request = DeregisterTableRequest() + deregister_request.id = [UNITY_CATALOG, self.test_schema, table_name] + self.namespace.deregister_table(deregister_request) + + +if __name__ == "__main__": + unittest.main() From 1247c946869129d090a969e29607d5295d42640f Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 21:41:32 -0800 Subject: [PATCH 05/20] fix python ruff --- .github/workflows/python-integ-hive.yml | 12 +- Makefile | 8 + docker/hive2/docker-compose.yml | 27 +- docker/hive2/postgresql-42.7.3.jar | Bin 0 -> 1089312 bytes docker/hive3/docker-compose.yml | 8 +- docker/hive3/postgresql-42.7.3.jar | Bin 0 -> 1089312 bytes java/Makefile | 4 +- .../lance/namespace/hive2/Hive2Namespace.java | 44 +- .../hive2/TestHive2NamespaceIntegration.java | 10 +- java/lance-namespace-hive3/derby.log | 13 + .../README_DO_NOT_TOUCH_FILES.txt | 9 + .../lance-namespace-hive3/metastore_db/db.lck | Bin 0 -> 38 bytes .../metastore_db/dbex.lck | Bin 0 -> 4 bytes .../log/README_DO_NOT_TOUCH_FILES.txt | 8 + .../metastore_db/log/log.ctrl | Bin 0 -> 48 bytes .../metastore_db/log/log1.dat | Bin 0 -> 1048576 bytes .../metastore_db/log/logmirror.ctrl | Bin 0 -> 48 bytes .../seg0/README_DO_NOT_TOUCH_FILES.txt | 8 + .../metastore_db/seg0/c10.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c101.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c111.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c121.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c130.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c141.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c150.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c161.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c171.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c180.dat | Bin 0 -> 40960 bytes .../metastore_db/seg0/c191.dat | Bin 0 -> 16384 bytes .../metastore_db/seg0/c1a1.dat | Bin 0 -> 16384 bytes .../metastore_db/seg0/c1b1.dat | Bin 0 -> 16384 bytes .../metastore_db/seg0/c1c0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c1d1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c1e0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c1f1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c20.dat | Bin 0 -> 28672 bytes .../metastore_db/seg0/c200.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c211.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c221.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c230.dat | Bin 0 -> 245760 bytes .../metastore_db/seg0/c241.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c251.dat | Bin 0 -> 16384 bytes .../metastore_db/seg0/c260.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c271.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c281.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c290.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2a1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2b1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2c1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2d0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2e1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c2f0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c300.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c31.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c311.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c321.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c331.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c340.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c351.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c361.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c371.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c380.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c391.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3a1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3b1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3c0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3d1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3e1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c3f1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c400.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c41.dat | Bin 0 -> 16384 bytes .../metastore_db/seg0/c411.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c421.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c430.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c441.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c451.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c461.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c470.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c481.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c51.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c60.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c71.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c81.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/c90.dat | Bin 0 -> 24576 bytes .../metastore_db/seg0/ca1.dat | Bin 0 -> 28672 bytes .../metastore_db/seg0/cb1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/cc0.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/cd1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/ce1.dat | Bin 0 -> 8192 bytes .../metastore_db/seg0/cf0.dat | Bin 0 -> 8192 bytes .../metastore_db/service.properties | 23 + .../lance/namespace/hive3/Hive3Namespace.java | 68 ++- .../hive3/TestHive3NamespaceIntegration.java | 18 +- python/Makefile | 22 +- python/pyproject.toml | 4 +- python/src/lance_namespace_impls/glue.py | 534 +++++++++-------- python/src/lance_namespace_impls/hive2.py | 335 ++++++----- python/src/lance_namespace_impls/hive3.py | 178 +++--- python/src/lance_namespace_impls/iceberg.py | 33 +- .../src/lance_namespace_impls/rest_client.py | 4 +- python/src/lance_namespace_impls/schema.py | 60 +- python/tests/__init__.py | 2 +- python/tests/test_glue.py | 566 ++++++++++-------- python/tests/test_hive2.py | 321 ++++++---- python/tests/test_hive2_integration.py | 200 +++++++ python/tests/test_hive3.py | 124 ++-- python/tests/test_hive3_integration.py | 214 +++++++ python/tests/test_namespace.py | 12 +- python/tests/test_schema.py | 164 +++-- python/uv.lock | 30 +- 110 files changed, 1953 insertions(+), 1110 deletions(-) create mode 100644 docker/hive2/postgresql-42.7.3.jar create mode 100644 docker/hive3/postgresql-42.7.3.jar create mode 100644 java/lance-namespace-hive3/derby.log create mode 100644 java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt create mode 100644 java/lance-namespace-hive3/metastore_db/db.lck create mode 100644 java/lance-namespace-hive3/metastore_db/dbex.lck create mode 100644 java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt create mode 100644 java/lance-namespace-hive3/metastore_db/log/log.ctrl create mode 100644 java/lance-namespace-hive3/metastore_db/log/log1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c10.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c101.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c111.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c121.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c130.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c141.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c150.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c161.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c171.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c180.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c191.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1c0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1d1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c20.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c200.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c211.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c221.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c230.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c241.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c251.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c260.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c271.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c281.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c290.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2c1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c300.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c31.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c311.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c321.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c331.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c340.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c351.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c361.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c371.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c380.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c391.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3b1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3c0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3d1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3e1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c400.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c41.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c411.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c421.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c430.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c441.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c451.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c461.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c470.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c481.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c51.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c60.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c71.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c81.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c90.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/ca1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cb1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cc0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cd1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/ce1.dat create mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cf0.dat create mode 100644 java/lance-namespace-hive3/metastore_db/service.properties create mode 100644 python/tests/test_hive2_integration.py create mode 100644 python/tests/test_hive3_integration.py diff --git a/.github/workflows/python-integ-hive.yml b/.github/workflows/python-integ-hive.yml index 3d118a9..c36ef01 100644 --- a/.github/workflows/python-integ-hive.yml +++ b/.github/workflows/python-integ-hive.yml @@ -17,8 +17,10 @@ on: branches: - main paths: - - python/src/lance_namespace_impls/hive.py - - python/tests/test_hive.py + - python/src/lance_namespace_impls/hive2.py + - python/src/lance_namespace_impls/rest_client.py + - python/tests/test_hive2.py + - python/tests/test_hive2_integration.py - docker/hive2/** - .github/workflows/python-integ-hive.yml pull_request: @@ -28,8 +30,10 @@ on: - ready_for_review - reopened paths: - - python/src/lance_namespace_impls/hive.py - - python/tests/test_hive.py + - python/src/lance_namespace_impls/hive2.py + - python/src/lance_namespace_impls/rest_client.py + - python/tests/test_hive2.py + - python/tests/test_hive2_integration.py - docker/hive2/** - .github/workflows/python-integ-hive.yml workflow_dispatch: diff --git a/Makefile b/Makefile index 083a2b3..82625f3 100644 --- a/Makefile +++ b/Makefile @@ -156,6 +156,14 @@ python-integ-test: python-integ-test-hive: cd python && make integ-test-hive +.PHONY: python-integ-test-hive2 +python-integ-test-hive2: + cd python && make integ-test-hive2 + +.PHONY: python-integ-test-hive3 +python-integ-test-hive3: + cd python && make integ-test-hive3 + .PHONY: python-integ-test-polaris python-integ-test-polaris: cd python && make integ-test-polaris diff --git a/docker/hive2/docker-compose.yml b/docker/hive2/docker-compose.yml index 909d8dc..8877ba6 100644 --- a/docker/hive2/docker-compose.yml +++ b/docker/hive2/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: postgres-hive2: image: postgres:15 @@ -21,23 +19,27 @@ services: - hive2-network hive2-metastore: - image: apache/hive:2.3.9 + image: bde2020/hive:2.3.2-postgresql-metastore container_name: hive2-metastore depends_on: postgres-hive2: condition: service_healthy environment: - SERVICE_NAME: metastore - DB_DRIVER: postgres - SERVICE_OPTS: >- - -Djavax.jdo.option.ConnectionDriverName=org.postgresql.Driver - -Djavax.jdo.option.ConnectionURL=jdbc:postgresql://postgres-hive2:5432/metastore_db - -Djavax.jdo.option.ConnectionUserName=hive - -Djavax.jdo.option.ConnectionPassword=hive + HIVE_SITE_CONF_javax_jdo_option_ConnectionURL: jdbc:postgresql://postgres-hive2:5432/metastore_db + HIVE_SITE_CONF_javax_jdo_option_ConnectionDriverName: org.postgresql.Driver + HIVE_SITE_CONF_javax_jdo_option_ConnectionUserName: hive + HIVE_SITE_CONF_javax_jdo_option_ConnectionPassword: hive + HIVE_SITE_CONF_datanucleus_autoCreateSchema: "true" + HIVE_SITE_CONF_datanucleus_schema_autoCreateAll: "true" + HIVE_SITE_CONF_hive_metastore_schema_verification: "false" + HIVE_SITE_CONF_hive_metastore_uris: thrift://hive2-metastore:9083 + HIVE_SITE_CONF_hive_metastore_warehouse_dir: file:///user/hive/warehouse + CORE_CONF_fs_defaultFS: file:/// + SERVICE_PRECONDITION: "postgres-hive2:5432" ports: - "9083:9083" volumes: - - hive2-warehouse:/opt/hive/data/warehouse + - hive2-warehouse:/user/hive/warehouse - ./postgresql-42.7.3.jar:/opt/hive/lib/postgres.jar networks: - hive2-network @@ -46,7 +48,8 @@ services: interval: 10s timeout: 10s retries: 10 - start_period: 30s + start_period: 60s + command: /opt/hive/bin/hive --service metastore volumes: hive2-postgres-data: diff --git a/docker/hive2/postgresql-42.7.3.jar b/docker/hive2/postgresql-42.7.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..fa42b1d6dc01046952a0c72e42d2f40288a19c28 GIT binary patch literal 1089312 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°`a63Of)Tq$&LP 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

G8{v$#* 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�(+d1l%|g)&$v_3 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%0Dwuhk4_r*1 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

*)sb-F$FWXrd7(d*#uQ2bw>=J2j(Qq= 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

st%XVRsQQ*sqbuQf^cS6k)i| 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 z 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

RM<#la0+=Z*-@bDTTmh`z_! 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

os=%(6-TUNPOLg?y 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

h2tb)@i9+Swg@FGhd|T^f;`AO>`aVkP?V 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

uHx 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%0A7wWctaY#7&vCE-$0`n5JFa&T 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�D1h$yEMM}~B(+^`q*o-!+Qa>cF;mpx3HNta% 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%0Apz9WsMP-fX_|rTl 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

6d>sr1^T6)amXXC1dd~$e9!dn9WZn|i5 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

Vxu*%}`b?=p0vlxIZaGe_G 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

OItElf2#w}$*Q%8w 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

G8{v$#* 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�(+d1l%|g)&$v_3 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%0Dwuhk4_r*1 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

*)sb-F$FWXrd7(d*#uQ2bw>=J2j(Qq= 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

st%XVRsQQ*sqbuQf^cS6k)i| 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 z zgyCmuxo_DvoQFM@nSa&si)HwcyI$XbzsrKEUeVw@L8sG8&YtiS)nM3iDa3GG_9Wf{ z9hXCPbOz|WXT$fDMN?f*tzyV9MCZ2gvR2AY=&{oN#sX)O6s1*)wb9FI{S)FV2@>er zD+48<3l%SE3AvLA-xE>%XaEPWado#G@ae>DSX#QcMqE|p58X&ReC`46_$04>)Q-jI ztkOZ|SVVFi%{eFD$p{%>6GDFkI4#8_Xet@L@b_B~dD^<4{P}nEYT!18{B6`T*rz{% zVLJ>n9hv(&j$~Mjeqv5Nq)9JB=)j8OfT=K1p++-N!H`?7LF0sGpKfarBgWQ%p!#*| zS%LUqrz{Wzb6;9+2YXi5nV0-ZlpI1h>|--+eef={n?OlfS@Np!-O-x7UyKg)NG<$E zkvQ48w-d0-M6f`Ulb0Waa^kyx8MI2GU+#b+GGQ5C7n3Jo7>b~Hdd8Ph2%zTw@__!l z6AKVr5)^tm_%K|)8_q+0_ns!N`0MHYPK5d@DfZX2I3V#?z=L2Z5)^Qv+)(Y+UZ`V{ zN|hlsUEg=bs7;A1+WW~F>2cIY3thg$ZYxIda1GB9^)82atP!ahlP0?p1D&c!{&Z5G6! z86V05TgQ#^u}PCQ!kfpZ(pvIITB*1W`oN&(sqnQr%qo0NVcOb!jPaLD{Bt(AZ92Xz zJe_>tCqh4?q3vHPkgS3!L?BLdLUWsicN!Osr_8-S(~#|K3*f#m_vPTRFaC39S5%E04ZR)ZxY$wzwi(FBwf6J z>D>v`L(;cwu!k@v*%$LpQh&nV^n@o zcNI(KW@#rHO5Z^;Mkn0Qcp|lj1CUZqLvii}h1o~QGR;!S912e*1b5uSwQ7sBH*K-PJlsk;w46<2TVIvLrXB8isaazh$EBDOkPUTPdRnI+tH!6% z0l8r&zi=?Pm3ajEKoylJr)0bxQmNI8+sow?s_STwLNvWb%S%0&?W7fpSJ6^&yHso` zPWH_Cf-ci|*FK+xQ75BN6RF|{Wor2-%&S@Tgfo!QO zr&=u(T1<#8LM}Iu?24cd(@O|e@q2*^8Ae-bsB8$(nAC3GanHO;Z=hAxH2aQRv6V+_ zYb0l}x1Z!9)=m#0xw!tEC9TaX(9F|yh=aqPZR%cV&S@QmN^gDUTk2W4)w6ki7?5f0 zp*D0r&CG4v)vG)Cn6$UNU-e>8ty&vNXI$0OhOFb&W&(tG0x>F2oS0`kFGBiJ_FK92O?0n0>uU1NQ z6|t!Oy&A6+#+-%5jn+!6E<@IA_)>nQ9G>BKNmGNIiSP(1fgaB1R-$}~1^QEvLt!WW zKsQT*F-QeRRxWl96owg`r2nx_2~yjV6Y`82_&~3g`V-1fg|X>}*7|fAYT&&#diHlV zxMP-cmoK=c%#ZjP5phFl(AR3`G+*!ysUNg0KVEfE2RG7e&#r&tp$5`u|IjP&-}753 z$E?^T9?Hod%dKb_qv4`GNIuykAL65cL(|G6yt6ptbMC#92A-Q0E$A+v*s0m4oqP!e zYi2;~+g;wBI3v82&UJ18_qt5V9ladjLiG}VPvJfjc>8si;rNR;Ii+*9BtXdCc!y#V%j}5c zRB(g+{)G-{O7cAt+~GM%jhi(#)pxAK`IH34`CNwX55{M7o*)$&R&X&{g39r{X+`d! zJxov#J@l@7D7d{QVG7!7Q|O=(CU`qONzj`6R_kf!UQ!cz4r7i)>(0tunvlN0Y)RYC zGaA32(!_#EfqH2K&>w#wrrDgEKFCcP=5%hb&v?2vFDOj7%oyB*AAA|t{=M&hfa}^clo{PmZ`)K&)jTr^U_j}iux*-~wsofS*C%zqX0Geh_Yy^X z(1n?7Hx8y(-cP0b<$;>oBzR*J%Gh|2kVJo#8yYTvcnp?Y#Y~iWlcJTPWQjO|VS&1YMcP|7hf{u; z(k^@7;qt7k!L^PtiPJWXi|~QyeVGXLJ&%oyL|0|*YWk|V%;h}S?`8j>gURygp6c%_ zRp7+EWl%`H=G6Lbx8Z&5yX@MHPM4VllZLZ;N2xIM&uzQEfU4g<;g<`lw286MHwJ9> zxY{&m^kd-e5Ygpl@j{=ex0~NMAo@)9D>mKvX?a{%8uM=WGf#FKS#)OU5HB66jQoZ_ z|3q7_o#uy|!NNRIp@_>6Uo~vI1&QvowHs%Zq)P9BKM}V>kk;#CB0~iEVazPl;i5L2 zF}&rQ1EArr!bHj|b6fUqC}ya22^A44)2ffunlm){|CpDkwXwr5d9HD6K*YPc-6yMi zaPhCus#q|Ffl2)-L4tx9cTZk-jO^{EIB29`=YJ%AmvrKeLWzYTpHrXF6TH*LY?64I zb%vF6WS2fkfW7HTI1{ms8@1wQOiTo*#qquoE{Z~?#_E*16J(JSj&u%MQ8{_9xzVPW zKJcXslArX<9aQjtl%H8=VtP(GeSJ#Q+1P2tGZFL_dSu$_7J}?l&4w|C;kfLxe#$TC zxPFz*>C8P>R-}nNJ-58-p=!@UkIq)>cBs@wl_cj-WzI`<(IYK2bhr8!?s?O7x+J$S z9Zr#lJ0%x2(jl%ynW3T))ugN5YeKwVrxS5gGnZm@cji$QFcbw+u47BTAE!%!f8d^5 z2Y<}YE9ft8Fj78vS(~}$BpC@<^Ywo&?z6EL+3yx&uM|L$jt&|D-vE29w-z9!&+VTB zjh7poUq&(KP#v(>#+_J~c73u82(2|b_W;AR^ea+tnMqR&mY1w_V{NgF+dCGM)KnSntMco={gwYJg zp7md04a`>F9g=Zn00i+(##8Yrm$BBc=33I3ox;Pb^`hjI)?_|gddxOPkTzU;4$3sy z>pmLt86)gX;m_m%HJm3#c&JuuqvY9N`l5@v9rXF&HqxD*Q7n77FbK7UeHJm7K;(wn zeOL$;__1Y+s=Cbwea{k>cBGj{rfxS~T1%)zg1qnE=!U7&S6R+&OznEOXTWvfs zX4LIibWaoAbp5y zMG2akticyx(Bjm7gkQ{fGunG$K&!#Gt4+2^Q^+C=SOnRlQC;Qgwx5RIYQ^N>QOxwv z=hWS}*ITP)AS|RW9GNt)EoU+JWcZHg88X|<%~7~L=XKOz5*q6j8wH%qEHK9Vh8#}c zy{2Axrw_Vx`a$H zRDOc0U(3~f$?1ygOz;}qW)Gd9eBwmv8|yQ{i!9+o>Wh29i=2;y@~!)}70$db@>(l0 z87Likk8Dg@SB8dKw2pTq7syOlj8aTcvfjUqaE9KdfM%ZVqY8V5V_}VE?hBRboGwXX zcEU4nqML}-giJaxr))D5K8d9}$V7d(RMmr>32V$Y&-(A`e~FLwDB_hXR+K)cgkiHg zls{DJM`INCTCA&PqoUFV%p_MG$$U;&rcoq?77W!6Xb!?q`$$*hg-2-1)87!6?CyD` za~i^*UxI^Ov2-N4^aW;m=6r9=4uhM#qOG9UElOQaX+p6n4Wng`>;u863MUMVi(IxTUu(sKCnOt9pI$6;YSId=vbG zX~d)Ih6W^&-r3&{$n7#rn&MhAL0yy}YK7_+n$WPSe1dQcOT$EBdcb}*MdeJt$k(^LCREyc8d0KagN}8w=zrfF1V43cWXg-l%lS zgRa@t_4yGxa2o|wtR}PiPtQM1VY&u0s2@M>QU0eDoBF>;q&nE!o13~?JJ^%6{FmNa ztT5~_GrHKtj*SgQEf@9iHnAs|vLgv>exbZ5049oZZKMnMgHR^6+v$S-oB0mu(R2Uz z4@_)i%5@t5=6-dB_m*>cb=ZDQS=(52JG(j8d7;o+ntF(hFlAp&&Z9A8l<|SNtsard zzYMHT&?EAZ_Em6qWmK^m5?0r?CGE}p+tG=HH)Ake^=-4xuE-}f(9)eW)QyGo!h%}x zFGbL;AE5uSRq2YwASn4at;2uMe=jM-_P?39u!)1StEhvWow2>ye|>|b9hniKe^OGH zH0|Y_&%Odhg&1*I$8n@m!pPCl(SLH>t7tCkDXSdFf0Z4A^aB6s`Z{qks5QtKxqlxO zI9PBU2o@Orcxe>dTsL0nTT$MHH+LoKtP9ulV9HjnORb&g*RY+)M?9&v?+CNeA`V_b zMH)s3wduYvh|$Mf4qftpZZ1g$f?AWvQvVIR#YQvsT2z7)1^>7+6JhLsE@{&rwy{(C z0O>*UJDZRUeU2M?nZv^yX?&C_5|eVk))(svgqMK9Vaq)H$NKQ0-6tV%M<=0^TN_UW zIcJ$0thSdDsXC|gTDSIL?d4n;bI@9GL)nd7vN07DT^-k{dIRM5(x@+WQ@ zhO->ZfZ&Pm0{Od!eoZRDJ>Sf0l6TyqwB;S5`Zl;Jdz^JLsgF;{vhZfM5#}WKL)yY> z^niStf8D=0sA!rl*JJic8e%2SCpgVV!ODGOqok}c(KE8e*O`%0{Tk~(k|}6?hXMGf z4;A@8>O*n;Z<48EZfvG#5AYH(w=#COc5wdBgyyN*DWVA@`?ou65JI&=2qR;Flrc;O z5%;GeCl-=ek2-Fb-mkRho=rAYY|w=#^nVi5L?Oq8FMLy<+_bZZM~?4P@NxAl{Cu39 z-A^bm><7~t6bt+cRd2PEmx}dw{}~hqq+M~Rj%SlS3w`fRBv<>wUbnnlOcsC&9@2X;M+n*) zp$~p3`Wl9|Sun*8Z`Q&q;~2&V28{QeMQT`me@+u#k=0I$4oILpXUSK6X3w{hJ!9MU zDZXk+C0`xxC@zUk29GlIN6PQr7u(Hd3PquDmf11rFbOqs7R7JsukfTa zk}70k+g3nF>y$B%nTS}D5Gu{09hpOHt?v`$yTHi<&AVWdq-h~X`TRbLKlBL0C+JyH zk2h~B-_V+BD7kX)20tq8DE)?+kQ(m;;y-GfIy*)= z;9q^y{Es5!LjRi@S93PDcQO7yUHiYSjJss^)W|=x1U~eSMGc- zd@o-7-yZML0_6d$yN{p#cBc@=2UtUR73~|>I&BwU=@;F@uyzX!x39Yho@O1rM~OXs zR8QQ)nnT#@e`h*=8m<~d8{LGm+<+j3Mw5%akl&6I2F&0@w@lYavDM~pgN`Jv(lSY2t2LBwVE zOTqMR@F{4~D2~Z$XE=$6MAyK}suI)IUsB7Z8d@qHe3{NFQkZQDjJR4Z)Gg)8edeO8 zT1ee&oGlws=TT&}SDrnCkC^PZkG0%4(tQ%_yHO|G`e1svcR9!kA~L#)*!THQOExtS zEabOqA5dBhoB@fEPi+VsZgh{EZlTeu_`>E1*x=uK64Oed+YrKcmb~N^5v(kp!QdaE zWuZ$DhZ3F0A(SSCVA^T zjR%v}S}~n)QYe48N>lG9sRa|&{Ye`>qirxKeVyvi)paHis<((0i~dA|s5r7|023Fb zx9YU{Ma;ebjKPpvq^9H0$&^IvCI$1Io{`Fy8K9M>F`6QJkd3bz{zt{Sg8YN~{j1o) ze~g#^eu<_0UsUXWHsR4e7+g~GQcUj>7v)i)ga`*FVu7MCd(90rLm>AVAXAL9DtwUV2Np;84&VFx^ z)mB|syR?OEb(tXEHG2@-%ns2WVcrJGy?w5FrxC|6lNei0#(D=eD%^qrZd~N|I&TPo zt2YZgdMH=)nXgO$9Z+`-IOwNurRn6rkIFt26;qMLnUxD#T_Lb9P$&55=cDaIy@?a8 zkW_Fq->!mJA_s|vxHKM00v}GvWyXBc=nZRcg_M;zMm+L1ZFEEuv4f4^J|6tgMZdg+ zas$v0`nwI2fe+~g)~`?y?z-tBhn=NBt=+(mi(udI3lPuRKtKBlpt`4{e;e zaTfvSRLVW+vJKj8f_m7$tSWyy2NlFtewYydz)9J z1z4}*A9~SldyT`yXwS*q)^^#7j&45D>ttQrCS%ZbOj7fam-nN_yo_oOt!_db#uIT% zI?)-i8B%mnZlze>T1JZt=k2jnuG^%qAmn`NXpOj+SHBpC4oRxls3}gWS8C&WzwPW=-9r3P6aIGB<0#Dj(krKkX@kEltPELix@4=NZ#T0Dgz^3Kd zYvWw0wk=#8?qH{?J4t^Yv711cfPk|$bKsMKW{7Y5@bcm%>g^q2M@h6JQgzYcUcpL; zaw8ONmP_$XGirp5)fL4J<-h!%R`QrBhs;GG9~_5vzJSan;URxksu${557Si+Qk2(z z76+sMAX(aky`k+S*(LlfVU*Q$xUQs09;+Ag^${ZVz$$GA*RDmOe~yyZ;48K}WHC&*7Hyw`FSz zjjw%XAUQvq8w13I7zk14 z&6C|+s4|Dz36Vh^nNi%RbaySf$M0OXGh%SWa`XHbOGe8P=QHrVTW=m>YFDR~)DfA7 z5O|!;ZC28>3>N2h{hbi02O&r*Rxja27~KZmBVq;Gn#fBs#6^#=|YcdR0IDlD|p0RaoEhGn5TgI4F8qluk=h z-XS!n@^TJyHh624q@y_XPotoyuIMf0Zu~86jSU@gYetexn&Yg;@H~7cn16IHCNzAc zh>`SR?3U%*;RQ81TB$x}R3bL(k$ozzZpbZvQFk1*0?O7^tIXya(-EQIC#ZYT5O3lV zVA%dtmfqA6FcheTMC%6V3H#+HcymAEw;021hacEHe$0IJr)*T}nm_C}?C1U>hK=^A z9ga8iHZHy}h}!|u$7kVC0~By|53&{p>D^fHb30hPG1KD3*sNiGku&3;UN7?rP)-Mq zFzf)ib%I_CR2F6%4O4AM#@l;3IOP!B`@Ifgt}#5{pQu2MV=T zD*eP0pg{i?y)Sr=Rxf+Tn2V#kqQli#RnO1`3a(vP!cJDBhinEjsa-QMSgF*y|G0=1 zgTon}DJ1|5aXF%?^F|7slVIjgVcU>2kYve`k9DAL$(L8~eaoQpxpu^{r)0JNQ~S`~ z_&N{^>Ij#9iJ?y)`t(0H&7x+>k-4_5vB}T{M5Yb_sJ9=Euwg{Z+2RR28RoPso9NTy z=pqn^24$2Wzq6H6dr4B_2B-GC)gDp6-W;UYP!^H^YLGMLCCXZ4mfy2?6+I_p}>hHHyj>g&kVcF^qW8S9)zIDM2$D8x%grmB&D z>)VYm@Dt>w%S&kf*nx1YX>w@1Zoy_NWy}V#}Oq;x%`x?obo};TDqR-dbYOZS5)zmfV8wU5&>uRZO0gaoWYe&kM;AH?y zxFrA8Ha$0tJjM%`_rv7{7zJ$ri>`=%N%E|lP#1xA3_*=es!k(ee4+hJ@^KjSxEXcD zoMUZqNz6|zwM6dqGk`c{4f$UlGTf_3076=OM}-np9?*Tqs0?$W$;L)GrM$@u%PoYR z(r-5YPm6l3z*KnC7a)Zr`Ap@^qOB7yJ{?Z?#Ii;kO-4J6I=OgoMj1Ed>b3^XV%HqOSeBNpU?Y4c2P~Cyo=)?L87nfnZT1-MJ+b-xw z7obT9NxK>Z!&*qUzGaPb2RmC;16-IxV)a3oBr!Z}0~fAkj=e#5v6G-MqY_uAw**mb zT#c<(3QGuzo;~Js(K9S^xq#Dp2?9>~?}|wUDbpdga*72f`+A8Mz+SJXde~$yy2Pik zw}LHvnX8ut-{!f=&a6~biA7^=JxZhk9^pP!JIdBLH|_SuRgi5H2eY-(%_+TA%RF*q zVqO}n$VQ#q%i^DRi?%%u<^KmhK*7H)-oVC4G!TZrQXkDa} z9JQ@s+W27CFqr18m6A2F!sy3-b}ie17!|DZY!ioTSHIrRu4Xq_&;_Rw6WxdlvaGJA zrmE4$Zcg8sN_GEChW?r^qp23V9cnY!ZR`#UYVZkx?PTDqudA+JR$6wPkNwPoI#qrb zS}3b)kE^X~s%@^Ws9oN;!eYNri{h8~N_oTa@Fjx^@4+W;?JcVEHddS{sKs`%dui$K zwx9tT36J~91x8;PvgMG%&o??HnU^%Ry!9IrzpJt$;qJ9mo_=@`ay87nwipJ8aYKy&~Cg4R2 zHYmyX63$n7RYU2r>I$5y>eV&1%?+isRgG2H++we&>aSX`T2+5d*_CrG_Ge`=zJUcj zJz*5le?f8(iZh8jX0BdcRqkVNqZ|*mww58WiPj8G@e(HKI(YD+f!h%yzRTXrWKXca zqSRXB$Iwd>T|MZQ9pzy#3@+pCB8z>&zC`TU zSLsZf6c#tx*9^v&mo}CzD{ZJ~M)_V!Uz*EG%T`o0S5{S2m*a{%C{gBMPmb!UCfL2n z^l`ChgBuGOD61q4> zLDfnb&Fbe_e)bK|wxA6*A{mvavNK2Y z#6k%}5`Aw~JjyAyty1TWUs*9~Sq|yx+|n7@)>$1wyM|)+uBC-Wbz88#G}_kF5$fzt z7)YF)mhMEdgT?1j03(ARNwL4b`tfN&++SD2kF*3)$n&Go4qDydY(Ki*AuSg1#Tk4d zUqY}W)sbzXs514Y6{OepvXJ;O{8+U8cqw)gI>Om%A9N^-7?5f0>$0OrXv2|T8n^tG zxyYPdkm@iIYAIy{?dQ8_A+s=ICSQpwBp9nk)F`r zQ#TMk!|XH#>F8FXyywTOg;h_{%umsK;*A!}kv<+@LzuR zk}9$IdIjl3Wr(wxq4t$_3 z)={Zw+bYoFA%*wG_>N7AXNgmW%flBUzZN^N_-4Ms&%=C+w^@I9_>iwsh190lah|Jz zTA-0Fq0aE>XzcPX6HcVb&lS#hvJ|E%otx5Le=@ zOZmO1);*>W1$JzMvwP)%07_pJC5Nst zFFs`d@lEA#)qi>;i$BSq zrv87c0;y!8)KG##vhr0a3P-1weTyW8OqsSO-6<4R&(i)K=g+CA^zq4AP*c;{!ZQzQ zq}(lXoB~u$-I10ElCEd~03MZ*0Dt5!p}WXmrgWdyRwo;0bb)6&4$1je2$7b4E$&$- zS26jY)us#yDZ9+#Z}LC+`5PP^H*Fi1F|a~75^QDfQ5Ot8-MA!r+PjqvRCuUqPE@w| zJN!MOGN zx{KnHWs#mvl+PdY>*>|M)GN}53NuuQ|0dD>0Y~p{T5Ti{RmB0cKtuS2(jh{vfeqUO z-J3!I8P%ETGTGosVjwYX7XOleMLiy{_^UV-NRn^V zuBAh)6dB?oq5#3Ltw1NP7?qFnX33K7Xium(uszfra6>AXv1AElXZnPezFj8Q4h3fHnFYbEgw@}=db4Jy=a&a4cvd0lY_3EurU10omoXQ@5;GXCUD{kBb^ z&HyPhSsXeIJu=iEGkszdGG}959c8wzZLY6qSY6%NV2M1*4Pp#B#VsUZEHM`L(Tq`Y zH7;s$FR+^!rIw6#lQj|X!F4Srh=89xC??8rcStYcka;I+4Tve!+f?ig*L_(}G!}^} zhtg<~U+_g+$_rX7l<-RYyE+!Ki%t8RC5q)HoG4L?C!W4lx~j@kZ>HyYS&gzLiejQ7EtnqskE zEFny!>tpA%Ej%ofef=_z#gh~*O*r5JeO%E-Y(33ucgkxKmWlFA2#5+hB<9kIrdW<^ zs;np09qEueKY@;5S1f?4A9=nz;B12+zau$^)z&pOSJkYluBfS~ZLBD_#BqwQ;xp!)wbUojk1hQ+X(V1wGG&&CRercn96vzR zY}Imwi76Tsf5!{tiW*deN%|o1R*N;6>4t>~^L#NoH{mSj#A=_aw3f3>96cVvXgfm5(*o-0;Ysj~jXjkAn@DI6K zeEl+0pcyx@G8k@0f!ZChgZmDXMASAK@)*)`cw*Nu{~U zW2aGQ-)%~`Ls&d?TJqTe_e-r?s#JZenzxJ%i8&Mz8i03>w$uLr2WH|MC@LT=E|E6l zVQolBs(;@vE)|y{b}jhIgNR;D)#^>`fCUCHtX(Pov;{%wzsjsIH!6K+i64nIwC=7Z zD?8TEv!O*z&Xj^d*Kk}MTq}M|t#_n|-vN9Msm!ku*OQHbp8c4_>w2_H(N}fJ^&8O( zE(>;&+>M8&1GwsySoVpVz0K`GxcgSWxJlebAqlC_y^`0yJwwir(h$dz6^@n0V&OI! z&aOm3PeG6L@vpPQPsPuOWIxBn-6m7XHin|oWT}a?N?|rY3SDwVr2XCE7evTkqRKjq z2Bz4BOSM7jD>{a8czx^^_hpEC#r;Z+uUf7|W-mX7hTVsP4w;r>05MDS%P5!l6)I|E zwbU#SOZ*x>CA;YXq?PmD&iAmye)aMpWaSi^)keB2(Q9dSvBo2~UN=Ne^NHW!l1&*0 znj{?|oJ}0ea;#&D$H~?UM_bxMKJjGw3U=35)lBg;9m5KDVuRnM?{K>tP$g45L)BxU zHlKL*5Y@4gDW1pbWZL<}i-T8J_TNh=u;g~HPrQ?XIB+d`~$5oJCa+`F5Mhtz>m;%75@|;OY`8g zZu^BLKH=9=`M;5e>2L%I5LB-Jk-I;^Xm^a9X-oW1rpt)WD2UgyLG24!;tPHgm40cP zOU~Yim$dT=O^O5JYZ}WpVN2AIUSwVr%N$JB;OPcRhhw6rYr1R-0?M)8%Phx8HyEs5+0g-iQ(pO%A66i*6i zXe@24u(Vt??2(SjPdO4qQGLW`D`jt|r&uRqSEe>b#T;r??Ni$=Z7jNZTD~@pLQn_% zu%BF3GCLC?4I?bGun;X8Q8e*_vb|gfprzfVlG#0VbV|)dmNrG3irs3{Pz@hW3sWn= ziLWXr!9MM9`zX|kGPD_5F@tJb&9-bpZoyed)D6(dx{^p|`}RPbCj#M4$&nr5)>fRd z$i_g>-D0Lsn~AOgC5*1AXr_a>t^`s`o2@2njs>U4-ED0yh3wn61-Hj6?MS(Es?E2= z2)GV4n|2hEQXbHVr-a%Wb=pFiHJmu>Xl+7yXBt5&Pk5udJ7q(bA7LV{ru@8b(* zq$QNQu&}gxt$~(TBMS0u;r8|wp{*I2>S`ldu?ZKhyso05nZgDYCsZ{wTG}SnRhV)w?DN13isELk zT{8G!+8NBLkJpTba0X(ODYl`fJJ1J`FvMQORPeDi&!Essye;!-~45 zq}1=KhPrB*p%SRBSW{8$(@v!b_Pa!gn8mLl%{xTvQC6bTeU`S3-$bRS;U6hHyCbW+ zx>PEIrJW%&6tpw#qb&iIQ`lHh?$gf3b*j=_E$v*kj;ftUS7}hS)wQmQ-$CZ7uUJ(< zX*$&vGCkd=T}aBYqQ0uMx@sL2`?T*Om$XwH1>M7F%yDf~qxYj?1CgU@U;!D9*9yoU z4lNxoQyJwBbQ$20o|twyr*wDihYV&m4$=kL2r1Dh?MeoVzC|K`%4`OF+K*7^vWKbr zYtSf_BGHQ$apCx5bY8+~Ltv1dTqxD9pCYelzsM7AW=s5uHnp5$GOpt1R4wf$8DZ7X z#T$d=D+W5!P3}|qGW*O#ZBNGr+C|TG4pY6Ws_|lx@?m>7%-&e zPDIDfwaHk6+I(M{A84F3LKX4?Lwu@g+ zB)AtnovkuCV30E>rgpy)z-|D&2teDT^;v9;b`PQ7&tTl3Cs))g#P3NNIHnMc;lSHgy5Us-7s>8^6{bpb_n-4K{i4N_`eonpnvGTH$D;Qd=1&4kYUhW z^vmo(+Zg|y66(LlxeG@qwiKg;cS{|wjgNY)6qKk=gHei}qM_e`XJPbT`5q?JZqeC?4j(s^#uVizqLu>X5Z8?JwHfG{x^A4qfV~ zvZ@e5s=X(p2-;t%)?4)ScO($Sl_EXeHE3nfG4Uat$*2VmjaW`w`jI~d^W+)AKrDPZ z%KM&JH)?*A_UeE{n+)kjiILEQlgf;qXCt?KWWic_L{R&eJUHTUCNVB$$z$D^IH;J@ z=5>5gfk;I!4&s06OsxxTxoPD-mAFn>;^^XzRHva6FXK=SpnZZ+>{#j0n3IlB)zQ_S za=eE!66iee!j!_pPDzl5iRE1kWK5_t(v+3sju)g|JETHsDs{jXXqK)^A*vhdJeca# zzT<;7&utwP>Dn%L$2_uS(=I}=;0!nusik{d%9UE#)Q9->p|k@wJUM}{K_)0=IZ3HV za4NF&Z0#Pxces+~%g~_1;#F1UmOes_Bp1a28luUUw8W34spItJ16<^yPP%))wWnFn zqY&ILl^!6!hpt@l)C1~TEv(UiH5Mfr&{s)gPAf+SHGtJtW%9 z?rBFlEY#=w^`mu)XLKjP=6XWK-aAOtHH6SHp)^sp5=Yam5YJ9So5W~Ov@PTSh*^3W zI>$JWa_3Hns#dgVNX8c)wmR=2PDH&neP@Qm(XH znVDslzFJ>{Z}g_5ZS*p%gBCt9+*)~5wLIJwmTk(=)z;VRC;Ihu`bqMXsAuM-_(E?c zu%}SscrY3ZRdwQ;*?3XTTo~c`drwB5b?%jV{Ra5Vh3h~fkA5SFY0HS{V zR6TY$n0jR(4uEM|Ra4*U*SAqWB-7(p2BGWV&cI5$QOJVra5|~QGZ;+s?kTm6sh{PQ z#*`q}!q%9*rn4@*0!0}0UYpoUc*t9lXF4i}=h>qIG2U3w zTT{Q{aJQUSDip5r>sRVOvO6vF=(KFmPRnGcKlbZ82#BA6s3T=A&1lE&uyD};N*b55 zd~fPM@#{B|o#a=U5DKB}f^>X*@}!~MpUx@p*pAk3)o=5Irr(ZAFafJzhEKl})kz8x z>LM3Y|0!Cu=o63(l}msusk-#7+d+8;M^cI1p{I+kgL7sk5e2aHpX+z|^`Gf?JEL5d zK1zG4twaSveV23pQ*C^zTy1J?(hPA`p;q@ha1@m-{d)ZdS}lEv7c!$JC7r#iLTLY9#pwe~pr;xJo!{+j+r2bnO3DAFM>EG2aCd8gWb1UAvbNy_& zXX2WteLCRnx5#17>d*NhUwn97@4-`wB{H@&8Z7-q@-p)DKcZIej(AmJu;{Ra zNjlc(zb~`&m-SbugI8sS#^FfH^~;o4dW|IG>*TUWZW*Dqk3=YA9Kp9(f?(iL=}IR59b^_ zc#!<*FwXq{~DIflb=F*7fAgrlrsxqm=K>KHs2U4k9J;qUVTBS!` zE*fq}g98QJ(!-3jc}^bruX;lVptL1bT&KglF) zxJI20$acmm;yv`c$Jcd+DCpXOn#MiL8zn3xV8bEp3-9?=Q@NVDUxO+#`K`J%esQ|E zPcI>Y=X$lK{L<<}tX(>(*X7W|KE2>t`=gU0Q%To(XS*&Dt@FzIPS5gm4753m8y9+v zB(3%0#zuyWR*8|7u=)gn<*7*g|P*RVsGuL3M3qSMu$4>q2x^j)e2Va zLfyh1vG=!8pmzl2hA}0l2W&;z9Fyf}d>h^NDY71W_?EGizf1aWn>r#IhcL;#XB!Jq zXu6rQ{sN740sHntpK-cgZCOzwUex1bD6_%NjFI+KyZ9&bbWN{JM!YvXsjsJ%<$4rOxP8IK~zR212Q1#lE0 z_%jO@s;9e>4r+M(P=aavf^y{K3(L5NU+Xu1Y3xclnVlphy$5)Yv71`nM>*U9zqrZR zBex%M2E*NnORV#;aiU?ei9`YXeQhQrTfx)8H>Qaz^lPVI}lz30%B|FnT zv0*$A-$Zl4h%dVRXt8c`gC-X>sV_QL(h$GqKK0~uynK6EYEI3*2QyRbZ8&C7bcm}u$M-_OzBzZM5 zeybSCK{tZ0CY$N5&NI8(T(r-!@40pr4X>}LMx(eQ3EmsDd!alvDVhHQ`-m=YS;iyM z9W&ms_=EZ;dV0^|kLnS6`kTd{)O+aZeL9rq5zjs3(e&R?>whHtnSq?n!#N+1@QjZL z-p8mdh+&q8Iw_Ag)QU!4%=`5E`a^}rXF8XsOCD^CgA8mzm{NX&%sVcg!^z#2(%4GV9P&<@veD2pzHNLQu7Ef(=ayTaqknxhJgRah3#(_*N-}pK` z?LDQgX&jW>wGJVWnkaD4oRy&#%VfBWO)xoHZQFvK-LWLHm#U;#Q-d`b`l+Ul)aZ)E zGj0xJ%Yh8Vm}_i-Lyb&rk~^88$~&N0Sn%yG7qCl~F0#x_{tSv!gEB};TZ3Jcj4e|gEHg(Y#F!)SWi0LGNO?)TIZ7TXcD+$!O8cD(3QVOD za-iR|uwVYj&qBA|u173BgE!eWXs#7Y{kSA6J=q!1ma>%9GB@rnx=O!IUir<~pLTN{?T1O@>f%lNQUKuNvF3bgf zxX(Pw;>$Uyb8{h`!U(pvOViS4E=GHpJ>t{9uwykd3G&Q_WV^>_9!vMo*uVTWBWX`$ zkRKJp$ysKW`JuopPrgiidkm$AX;!Kgo7UM1w6g~2fP(C%xstYnobM@jrKJ0pX%G;x zYO}^~9%t4fq>b{od4kokT#fFd zyr0)>5@%+ZYs?ekKk5)SMrXM^A9G#eM7KB2hf9tVi5w@%{ld=HHQ{JCdJdM^tZ+RA zg_6q+Qpcs~#9fzt634}*8|3}WNmFWXrj3uuiC>;JU?SQcbX?1TVi-d|KLUWC zbKnSIW*a_pn2X=h36|ya?N4-+@ckxy_5sTQI9ir2^e7!pKYSrSm%vi_c?=vYKTBbm z{49fV*-r&jdbC~+E97SttdyU}LACs>fm-=lXMe7O;a<#I-Rx={N4qp$`M2%=9G8izaH4?0dpIimR71!CWA-aGvLg$(jP$< z{R$C^?l68k25WKr%q+Yg&M)eRi#Y6}rsih+Yakl|ykTy^zav#O_%2*5H)=BBdveI_ z_VuCXBG^j?1pEDTux}qGSWdq>1VVyc2?GBQU`epW{qRGP2KR3gZa~#@;93f8ul0F&0Mlwa9^XS)w>~RD^2ilMtCOaHEE>G)+YxJ}}KazdUQ&pWlhdF%?gKLp* zxP1CCJ_-3mcxbMX0{!9;j-5I#OCjJ59PV{G^~+cP#?Ma&AmUGO(J=h~jc}6EF!)~~3H~eh)UHN;a7@U zMh3RX1Q0!ieegixKG?su4<6bBj}&5`kMzRhd*Ded)v)w|J@9m)z6X9+sO^Dgu<%(d zd~OfCVB_@1UU;RjWDoqQa5wy=xEJ2t3xD4OAKWN1qPtVpC?qw(RvlFonVU%a|vr{<8N4=l5s7YcQ&pB*U zVV>T{+7a`3NoQf6kzCTH28hZ*&F*ftmFT$8%rhT{vK)3=p4rRJ+<^=x_OP>e!jU=b zT&GBrMU(ci^VjCE3$zDt&P1Nsu$Nu3oBgnlUA14|r+%F>i5*c|W^z5Bn*V{XDts?%nJjn$Y>a!opl%FS~DHMqysY9=4~jxR3Sk zX1`Vwkd3`Qh*&+;#~$6o9>Z@>QFo6Ztshgk{GLG{dv*_d9%t!~YL;Hc$3LmZ*YWX9 zsIe9nxkEF6c&;JDYa@hYC`Vp~@a@gm2{$6&V2^)R0R_x}CM!J`q8N0ck z9xoihGsE<6FCQlQ`0zb^MB#2eieNo%({&He!=kZNw1j_SX5zPb>_|4B9m^K5l46IqCFW^Mc;wuxWC!u$rdh2P2A`D3huzstJ#$Lv)81&a#K zV!~wI!eU!R9@{P^v(v>)c7`ZtXNx9wuGqlN6W#25DVDn+Q*ao?XP~C>ljw~LXwkz9 z8Hs0lDnbj5%co+jC*Tu)0WU#2Nn>OAT0Rq>bT*yW@>%#~;5c99v$39uBUr%apxxxd zamK90P$|~(p`ISX=b|ba4SDz}BxjET;VU=!+=HlQI57~uVfaUCt?^(Y%Up;ET?9V% zJs83+fuZdCkjE~AG3*D9Suh4PUdGF@lcA8sEAWX_^mtxL=Br~2fHDUBvfPBa@vW?r-lbNk8 zQcpgm2k!AX-KyCr+ONiEk0IH!?MNa>M1K*)6`RT zw)k2-4bK+esHdE4@tJxWku5$^Pr2Fr1obpBo3B?-qm*oH*vsosU6IWr*CyJ!WAO1u zNZ_j>mt6zn*tIZ~{TODl9k7612c_(KIF8)_tJzPWncWCsb`!+d&2SdG1-{E}g)7)? za6P*n?qGM|`n(hR*-m(r{SY3Ib*NEy^OFiuT-KI64nvDe_VS=AF5cyc%3;92 zh5(b&a3nDljc*ciAF#d1M8AUJY#)qdzs5TIp@2OE#q41mjW2i2|6|40vF9O+z38&tavem6NTgUA3a!ZQC-Y_-h2P>k8sO5x zUf#Jw^-h%T2Kyh5e^4^K9~R#_;>lmNZUBI)w{VKL+wCC6K0!jx%44IB-?%cK7J{V@B1}H z{rravYD@b0)eNojsrayip(0tmP%F;UdihWG@>_cO9ZkhqIP9O|KwrVnyKaQ6V*1ot zd-*SSLS}Ie-z97H^4$qKWP$cI3^VzqCcpAaD9kZkq<9bK?yoSJ{S9Wbzayi)kBaUC zTu>iEE&C^|VIMoBm<%KMh5SA_L+c%@e7#KyA2jg$`5qT3)VsNH2a|sf81LnM_FT`B zmOOxt_QXvo-VOUqcB+8rsw*=>y_sFA4&O_|;{E(rwzF}B4bCSGfBrxUM6S6Y`fTL0 zUhNv;_ydA{fxqZ6A?K&!In8rI{>Wdl8_%;F`=x!(Uty{KGcR&M@H-G* z<$tmvY_O%_=)(K?>nP0Wqo|j^wG%n4Xb*q=UPmAzRflT{VaSg}D`q|n=SQK9w8%xz z(GERF^S3F|gZ;h3-yL{%{+5dKG2XMo|DHBG@9_6*3nB;0&`5!3;n;D=mJjg{7HWA~ zQC3zz|46`mJy*XD#^h=J{1XQJCUPPB`F|L`*m>}8^lr5D$oT&RdSv8`@h`|3qgr1x zK!4JB949`{=;a5oOb8T!LfXt%mruj+N#GJ|6IlW~ zMgwlW7>-I($A4o*4iesNDl)pw!6p^y9umpTg}q`V5~`-SC~Kr7(+-;qVsxAgBA>`m zEU7@s-d9+HBq)9yrWE&!@eFoCel30*5&xFCP%A+xE+&=izgOCtM?)oh5RQZ6p%Fh7 zou-3v0A?VahE<#F!Goy2ltYC^=LcATbIcwzzpzarDZTlLXeghAa=961@DR-A8(|)A zLjxfUmH6&tzS)u9vmrx{USQ{I#AKum(W}{^W^)=F0bMUNC~d^F|KDkI+rYHxK-zR7 zZMu*)Tah-~kT$0wZB9qpbRcccIDFcm>3Dqd5);$oe1l4a$@)48z?6^~+6EfG#ILH7>yn0?JZF>QxB!M=l9wq={5J0y{$a6igH%WS%Bi|CB0XZt+mO zZUl=QFv%hoy~Q*Udsn)MO@cK`%(h{zmt_EBl?o9@JORTB_lbFH3;V=^J>m!|N{AEG zwWD0}_FkmLZWJQ-p%B^Q>T;|{mq&@C2k3H<>T(Hnxpa?ML`4I3`5<<=AG>@AyL{vj zT^=KjRa45RqWmHW_8uw8$Dx=$iuy$*hlj)plFE(YVhc4_OfKJ!w~0Dk zM#+lM7c6e*74>LH?Ll}aa9F74>5oHYo-Q5`D|*F=1g=+Xct|u#;omDlxGcx#X%CCG z9WXLadq}jAC@&HHVvE2PIWbQw?iHOo5g*aGwogRj%~W}wwu^e$Pmx7JH>TN$NR+qc z>3w25nnutBkHDiy1p0hZEVGT#nPAR70Mks-cmP(KVuf$SL9DCWk`Dh9r{X(Y7;tX6 zDV9mHZ$Rw{{8iMfe}a+xHOS|G#s&R0s*88w7}Rx5{C#NQpTH*mZ#av83g6-Xfy?=S z;TrxwxQTxTxAM>7F7&(Z=ik7u_(3E%hew5g$ApfU8Su0)#9ki3So(AZPE1S7e<^FlwrXj>^OuqJsX{(a)owMAq5 z#1B#yp%~)YoA5hW`o-nqhiYNUXbVS1y+T}>ZhEmjsQ`z2nO@>5-fcI&(e~lyP*_}C zlOq~?#dW>nC&*Q``@~IaZGR_6kT-)C)g9=ml=O+)QTD5Si{WCKz3Px9>X8G+$=*j2 zp~YwzCi1aL9@-gWV73_R$nYE($189;XrObPfzENJV~)5(P6wlVb!{R0itW}nDItK% z2X)d;fw0?<&+pm+$D+EsXSdjM2h6uu*Io`w$K43iDbPNS+)lBNqm~>+QgB?qcu+;s z@#$f;eWG|?2lf@LNx1p~ZDKJA$1(*bi)k>ERDmdjYEgvxXQnfznNWbv=LvF5P0pB_ zoG~>?rgVE;O_GUts%A4*7f_nO6j(Ax;y_zFlQ%`@+5pSxew{pZg>gl~4@i%-zY4KqVQuANr%y#0#r{v5U zWDlHFk|X}xD?Z-=4JBC_z2d8dT2V=_IJj41Sc4=B^36hHCrn#tN&%w@CF$~X6m@x; z6f>HUXOfsH%+vCW1d|=SoY?4UxB+ewkJ`jv1o{DJHpM>=!ZB$4feZzUf7;T9AzPc` z(E~6EWf9pG!l@Bw{FBj$1Tha+&5{i z8K8PN16wK>^rUK8Zl=LSG8XpPn(}(=k;?^*jQs>?_ZBkR1-YLW^lQV(ej8J*W@$uR zYiXm3XliIChTyu*(}p>*BjHNpbp+5`qQvHrn)fOsF!d9@vHk^dhV4T>F z6L31rKpvTcI&i)?2bSXJv7*PJ&PXWKCL*y3r)q5yES6K#cqm&`o9yt`<2J1pdD5y0 zISsvTG*uK8MtM<0xeWO*4Tn^Os_O`cBr`xeh)i}U62zSb8O%oo;zRLjiSHs6E=CRi zJ(z}N3q`_)_rVd)SQn+UA)5y`*`xcj?bB~gjA}ZA-CD^VwxOrZa+b^yWa#A=-mlHO ziIfXGvjYP7@xg9w!JRO&Fnk3 zm{5CMiVo~H?pk|4K!(2@wcQUMSHQ5Cdb@iZ&BXu3>bw} z?y<~esNCV|V^rKw(T;Uy=ePFkthZ<9nf#kcxZ%TfNaS9vO!YX!nS}{B2{|fzfTjZH z0DafO#B{(j@#&~Yn+^lCA^s^U?m8c(B8Z<$>@D#NlzY2St=tQvMK3P5ekc*YLe;Vl zmWcgOfm&>(_zkL-$6RyaioVL^qU5=#9B3}!nbf&>3Xynv(7E7rx2p~A6I>y*TAQ;* zE};wvq|;dK+$Bh>l|^hHj96R9`m`D$#`bH+o2VF$t}W`k?hhpjvwt)$?kZ`P zmynjPz%k-g3;Gn9w2-vuCA0jrPuq|bJPaspIEJ?R#5*`4??I;cD+I&`FiU(03(!(Y zOwdtj6Qt2k(b;&NVB<9oDI0QdYIAVfOgJSvN3V9QOa1)|HSs4fR{Y1+-#CxOxy9-4 zM|OY9)9BDK7#)TZ9qvXtp#F<5nMg0ZlE4hrcOWm*C6+%&x_pUr`3mWB5N074F4P26 zYPt*8Cmbby3C!8_P7l=MN{U^P&h%mM7uO)Eqot7wW;!7 zTPSQDP|5uuS;-aV_i9(v6h8qI)a$EM^dMjE`#Ld?xSOb5jV@xbauaI{OM10y;~cZ2 zI7z~0053Rz7LdI$DFuTz3&}GFa8t>?(_LJ1;rFNqe99(QKwxJ28xW&ET6!dineZ6bZ4fR;S zw>p-9J1Vg#p~%$QZT5;vXtyCkUaOyy@KRU*CePJ>JFb2O;Vj!+m>@Tz<4|(6pZ4*s z)kVGh%)Q!OcUPlICjj{{R=d+t{p>_jyE73!)S@s#i(!p!7^fwy=@H=5?&cR``*Fb0 z(fNghG{HgTmkufy*{Dnz2$iN(d;;iCy6_3c@sU9l?Oep?Jap5}$6DWkN!kT2oQBvq zO>*HhC5{tanQY@!Z||4osM+4lApaIG8!g*yqiOEQc#gwcIof@4-64FIZ^KWd_oD5v zmqD-gt5hDi+&eQ>yHDFk!02LS&)Bv0P&zkU?Gd}Sx1O~J<#ar(Jz__ZPPe_y0BYUe zpag$vSB;WvzjXxPGsQ9_szgDC;}0XWDs+bvIv9mZhIRw^wVyas;D?dgA5fli`8__W zfc9+i@{=ok81NCGJxWB7ABg62j#FGqo&fP6D^kOLk-=W=Pj;e!%MaFWM`dycWNWv( z2s+&9dU$Hr*vs?IDor6R_K`YGKlfZ{EsoKe0^zlE2)hU0SkPW~43uNj<OU6!}( zUwfZHO>qLYk{ypAu8-pUJO-n+$6bosl_sryAXg8vjP{}Sj}*oIPe+Ql_kq4nCGo3X z@)Z8xCBL*UytJ40RVs3ydLs9YlS%JJPWvj3+}GY&^x9{L+~>ExT>Nxo5@&1ErcBj!L+jb{MC8If;r5@JNmq3QT)B{yc_iv|X&9Ucu^?9j7E%nHn zWBQT$e7pV0c3Q|#Bpt^qF3uR>1i8$L@L@RdZcYA!CQ+!>hx7M4d>d4iW&R# zdXiWTsepp%!9cV|f5y+T0qnJp!z~w!^9y_R##>a7XaUJ<~^&&PcPo#J(erAyn-=}Y0 ziwKSD(>qceRQ(KGa%Z}jHp`i-ESYh}(jeadp#d}{f_H+pNm7B<9)-OjJM%-#vAbu^{*xM|D@jI-TyYH|IEg0>*eDMYb* zL0kr3ROA?YL&{f9P|gji_-7N(Rc3E zf3ZJ>uXkbp_qu=%^8orw{hon=-s=Ih7lHO20_bl2zJY=6@c{a31p2@sfc83+Oy1?` z)%T_@X!IHNM-M^Ge%(G&OFP@@v~U8)Uwh#ABm#ZP#k{UV$TDF;;;lcRKbY)*(jC6` zMtM1^XbOy8W_R>RZ3$XSk8zlyu`jedUleOz$taLE-r`>60`tN0uDea`^YOGiP z!>;1J`U{lBMonMhumdJL$vb&+{pD(TMqx3%{*wlM`k!}UUA?$pe@nnZlir#H#t}i; zAilvD>#>S%7&24?jvi@42{o*7vR ztYtrKPTny-6DwC+-{+((fUE9|wf|LKHqZq=oo4D3R>fz`dyr9Zfsf!AVCuPquBp}K>?SQ=-hKs>eZ z?Til+Nk8S!3SD|e7hh+B6}bNgiE~4(3%4i;c4ebKB6{|e@a}t&d^#rm^UV(32mM8V zaQ^t0DR!>}FGljz%GJA$>o;?E(YS5@;1dr``D|+Cw>qvREt5gUHR#E|?_ido6*aJa zF5ZRp6*KeT> zX)}uxSWrSB9a;f8ZW7{KINDEKN12hl+Dw0tgNhEh0$5bDXL;~aH-bPOv<5(ZYCL%(| zoOq$2!It=ByBf|7-K_ei0g&0$V&{D6rq2cK?ok(GRNdnJ77DlRMJ#gJUE5~XmZKu}eA^u8WTR_l zN#QB(>^YzN$Md_`X;XRq883+5#XjCmC{6;9Mj+|f=4*|_HqLm-t$^&|Y~09++n-V) z#5SI#Bs+q7rn!Fk`C=o#$*Pz@7M@T7m3R!>X2GNq9f!#5P)Jzi7k9!|BZxmaLs7Ax zQkd|j%)R;rmtC5HNv~H@~s?#t;;?_XW-x2R2!_?YX zhL8G{Z*}4lj|0O3&#IGkh4B>rcHDT7+~DRmp^Dp z%5)DxWXdl%$19C=xg^sk8L|b=%TT7@LFLX?4~JzaBnOL!Uz4wBee~AYs`D!GI`dUc zRb1`W8k-f#A+$S9iKNP<3<9pm2ZTTAXn!%A%~lL!2x5LsgJ#i4$33sL{+6rs6<#!~HqMzhcUc_JJjs_N8G;CRTV;AfnBKk1;x3};OP=q8!ec&O6ABGhw{@UUQRYIzwc;!H$3*Maua?RZ{f7L!n|m0I@*z4-TafSQV477#GwkFdTxq;k=5NsjahH<)vW6(He1|Bd*hMeE?wd$&DV+9 z_Mx<*SRdoQyNS+25Ct*3BNV?Vqhu2cf2PtfEq%z2cTbJ~jWyI0HGhfkxt$+!cNTR= z#GV%kfnaj-mhURkS$gemMQlfqnHV|<&fRToml%d7$~-stJ2j+EI=W3M1{`RnmoHdK zMVIJpCC({5+yJKB4uoho9+PYhb|pLuLNEJx+?vhAaK^LzKgSq;ltIoYtUcC>t7D(y z^m&S3f~*k^!>1Yn5Z%eyw1W#)Ht59mKP5#uwEX_eY7?@4z^XHCq1P_u}O z^x^S29yEDe53@bT`v(nzTVtJOIkFVC%P7P?4PMG?Tj8Df2SA;e#gSB{H}{iAx@N1kj98)Pf$P9`tR*c{{ZB?`M$pd4$>+xml`6mcw~?w#>Kba5wukVr`laAe;qD zgV=jH3`D=+@BKKu?}KTLp!OJ$k)7Yi^)7bvkKUcm@0-Eg*6%4vWA%BnIc>`V{&^7z57l`86$>)O|Vgbw`#8F0- zs~;$mHm4JKdLsQUQUpB;sid>Lo!70zhf(N}2b+72M?D~MC zV}%Bm<*a#-7(T@apmHWXPHsBnfO(KfSlxj%;M`2qp))a9(OsP>E&$+J+e$I^72zfJ zT$2!ebx75-=A*sPiu73sU($o)pz4ABVU;JTAs9-}gY8}u$@|ux8sfy4k2yTI5~liU zh;uV3Wv$BZ`S{0G-dyJp;*?b$9dN~NVq5gc;kmh4i#XQd{ntdy*1RC_Y(Kd_H{5`T;vcR7467OZI7ocNNSTqLBuL!Q zXz)@V!pgB(6<=i!;QOg!KEJZB$t3%_> zY8s?78l$CqM3DBvZWUc))1Aq)QRvtX_%k|Qe1lR$_(izAlIy&B%hz;%oqF1(V`7=W z_;zeJ_21dx^FPY=x%9OY=eNcuzvYMdNkNUfTtTf~lyFSu+`vm_RufF3^!~ALDFk8` zLkC>i!4Bk!XhjRs2L?#7|2YS#Zp5W|nmw;TUoNzmvxGXNM%SlGfBEi+w^YA>+wln> zgR^XtzkMGB-_g1~s(2J@?iT&$82wv)_+hkZ6}BhK8}Vfw>36LLC#!_gKi!KrjkT3_ zDg3ZKPf?*ncJuB^j&yt6B`a+4<6tZz_i_uhO?l76RBVr2bW96nI@fT! zRGopLb`Oxc=hvJYm6|a3$vM)cOcVG73Y}dQAP~hpWd{IEtj6O8P%alGH{Vv z*;}u<5uA)|QR}W4+tZ6sJ6Fc6DXjX5`AZ5%rh}Ovwhwu$T(!NTTWx-v{7-8nd`mn! z%gK*W%{Uw9Pd}ZNh_RD-w>$dfSX6?5S9O+?Q z)N56Lh)!5fhSuv=D0dZ3r^x!#QW4TQoH2WtsqLFc34vZ@;bYnEXw!<8f7TyFUa;N> zHz9n9dNTcdZE7^xeOGJ8OD4LKF4Fg#wS=07MT7p2+1Mw}%iD z{}_V!7=fwBgPzvuvQhPE z=T@p$WL21Np;c-n{TO(fPA-@})GS>!LCz|0amZiyX)MVD;jFoVi?`cPVv{lWUlnRU6a_ZOsBmS|op7x40uq2$U%f(fo^Nxd{!+{YoDrmwiRn+(Phb?_cKmf=hsUK)=f9^%5KjG45 zUnwh4^k85}7XDkfG|&GcTw2o3+}Od|!BYJH2BQB@)O7qi5d~KpG*&1XMCS~Ph$x+0 zrJ3p!ttE!oCM^{MXbP%Y+e{%Ho@ycCMXBoVT*6#XnGdY3U-qc@-ME+?kQ5L(yS8zX z7lua#oK4D`F7Tgw_TBmTaQEX&0Q`JtBVv!RDA}CXy1_=~x;aCD=!e3%A99$!4J@hr zo34>$*4-Vs>w;(oh(aN0dP1fF9^~sMQ2kXJ)W=(t30G*i)%~+f&k{dNH{?KHp2^85 zb$}b~Yp2bOU<#6Nd;4LCBD=y{fg{`Gr@1d%Yf-)4E2H79)ZMnBp=?)%Hy8Nn z8I{@GZh=07x8^m-&L+c5dls-vbSV1!>m^ix&;8?z3TCat12qfYoXb z1GI~}6@{nq&p=rfgZh#hxTd(JaFJ6h{Q|Q7jwZZOL|f`iO!cEq3ddQ2Tq_i>qWHb- zHpy0AD^n4M9E8ex2{alXx@hJ#*_lhZ0hg$nhZF9`twl@xg_)RJ+dGM+n=08}6cl0C z-vj=MMb-;BeulPnVippY5_u5=Qy6 z++tqJ?b_`d?BFkDe11MhlCk7|NHU(#p~1CFfqSMgN4!Z!Hzwi_rc5Nj+f7s=iY^uW z>x0Xp^C=D!L9g<*L192w&^Fcn*jNUm8`xY3o|5tG2x?wc>WI*gGrz zQ}-;zD_}*FU#lu($}$ns7;L4fvK)EwNz|NX<4;>op#|yTQX;=AM9XE1;u$5MuC6gsd^Ea?Y_w{v*$YY7%W zxqpNl0oAtQUMoF9R6a9UgjhuOW)AlZ?&y~+ORoh9`|UZU(!Dk3P+tRqY}@rz`ez{F zXqOJ2TvdgRS-@wr%OB9bgq|$Qnz646W2J~=$1Z(|zuDL{Z}8w3X6Ef+3dL5?+OUo{ zFzf=CP{KXavJrs`Q1c!ED8#UMu$G5kYF;h=QxLyK$Qj3AT!v8q$IyL0@qqiXTf^Q{ z{VJUG5ND5P3Zr3T2v0xn#D|>jSr9F#(wR7~Y|=JvI9}-n<<=Uux;AWCTY`98su}W? zDoNo-!SD}i#k>x8QlF4&hOTWe;RF7sx$EQ&!(n0k=8iSuMFWawqQ8jmcZ7k%8gC0_ z>-l35<&>(tO?_gYvSUm(ldh@tw(O{>j!B?f2v_L(dGZE8_L=!?yI~su1vsKVT6#Ue zSCHEVsko)1vB|@HaRQ#bVh_DHrC*mnkqv13)IDPUr-pFcJmKxX<1{`3|62`V|Nqty zDPuQd6Ju9%C3839|GfV{1X8@_M~$U-fQAD}R2U4tcT|u%+dLAESeZ#PGh#b8BAM}8 zQxEzo4p3f6-Qt1oX9PM4A@#wK@kQX`%~sn1BO5SV-etD?ou46?*ex0u_y%i4J_kx^ z(B`aZpwJZB3v7z-&u_8rtFF5a%IxO&E;Ue|m-T57r1jDFUl0keC-c~^+X8T?!L~XY z>n3B@^QX(3f!`SlCq_!ExMLReHn9dG<5+^2r4q)cwut2=`NmDz3vF%|SzW||_+-F* zd~7>%E$IdC6D}aFhWjPgdHuDmM-x>@UV`!|@M5sxh{2*t{N!UdCH$wAuV(yONtP1^ z{EY48r6j^+QAL?lIcYvXf8ve#xgt3n;2BE^oket*O+-B|Fjk56HG7Cowwii)K75=x zBAU@XrI<}u(VpWMXw)8^rfV1+z|NXieuOaO+GSt2YPX5~wUJtR7~D-!*PFnz2uhvF zO}F7a>xvAE=ml9u*>TinnMHL@b^C#$LVl4VC%V+iaax&kJ?1(rpkzC8RK^H!Wi2L+ z`AfWyHX=CAV%)Mz6Qu*{7!eog_2(Vbkj;sQ*y1Dl#3b3e1bOlcQjVg2Zv^Oi<@VX7 zmUkZJZ0+n9(EW~Rwx!uUe*W;;{?uo|IZV5$`wC4jzTne%o8b=^<~D@hOAN{Jh)>R5 zs;MMJ_FW(5@HklYjpAB5ga5#@5~K>s@`*k5TyfLG3`PXOUne{dnK48X=cPn1?&+M%}uMqnP2$y<%_D!bNZYr zjqEA?8O`!3Hr^40HWO{I^jnf~UFapVe3^dA_s`T7@7sAS5n;!_s$X%Yh6dtj6&G3M zv6)?PT)o8J-L0Z3DLB5$ZWO$y7H3ktr7ZdU!xMP@3=`y?b)PYVdxX5%aF?Wrxpzk8QBnrEId=$*U#B|b368Mun@6F^~E%$+L)`N)EOt@ zgAAy>D85_|9K;4-tBEsSTzOj@3wtgZ#(bN*dLGBj@jvmmIL^+tv?#Dm_!}MS`9l_2 zx0FnBvbh?1dh5oVOENRkazd9;NJ5stdPQcBb}}@)XIICPfo7`1kd{*8I@~)njk|Yv zdRwsPYMPvMxRm(nkF~vSkU57PY<)&R;n z@|#9UeImm_cYGSF4eL%>MSa>typq1Z8Ai6YGM@Ss%}QBCoZKO!LfY0WL^F_CXy-Cy z2%naT$BQQeJ|rv&oX4z+oK!PQZ1z&=-f8tn+N2W zah*I&C2y)1fImt-f^b_UO90d#K3mt2eT zK8(5=MFr9=chzos{OeLr26Y*htCKKL)hse9Qga2_dgF+aM zX=NGCd>wZX5g!4un9jY7iv|C>_^eB1GZI*ZJIs2PQStwBB_Lrx*OS2mAxZvh#o>pU#v~H=iQ7Ie(=8PJDce zT!9`207vb<>cCaNBo5qgt*xRgJFr6NJW_=xQiIktji&5aL&N?iqe1>jB)PqlT3Jai zU4{im6o5 zGdCxA8W%6^;>P$Z>F_K4r%5gEIllK4pYhpLF1_y4?K83 z^Q+|`3)m_}UX8A>KBn2QJC1iPxMw_A^qcrUaAP|pXe8CL1aFePfG4wgcI=3zM&SGe z^NJXRpDJX!po^hCb(LH>@slnbL?LsP{E?c$WqAzkdAmb*f*`ux0|K|oaKNKb60W*f zqkXemA8JKcdx>1^(}Yr0CM(^S`{c7SRQ`#~+jTPpo8~^zjAmaQ2H)Vo3jt?jgx?FF zGx7^b=@+yoSEnYlC)iYv^7jlmPj4R{M!Hz=c_1qICS8iGjOpK$zXtz)q0evTm_7z$ zp==7`k(1ev5CGuO2O}y5Up*Bpvvlsj>uXuf|E z$sc1_I=BZq#pU#hlR!7-V$c{6*vFc>NEn5|LGr>NpLDX|g5=4eBSmUZUJYTTPh9{p zLL&%9Pt3qLaYmch34wCG(!tnk0TSTzSD?^*)t5dbc1rN1xBLtqJtB& z;ALO{_qiqGAOay8e7Y%-U>afg(`nMD5VWaj=inCb*YROqaKX$djqWp9C>ZvEgO?iC z5R9-aH6@+IrMQhIqi$>@iVXx-7Liq3*;&D922K>hWv9eOGyDm{Z>hBw_rkB&ZuNl) zT8N#CzA5v{vK}8d2BOC+($c{7l7Pe9jpx0TgG`WZgiKMI;Cn3J7IwsOS4Y4I3}dE}3y_3v6tR@H0?C9+tR%*1+pi-sLq+1~;{K_+ zS*!<=rP<3;8!;-8&d}&gAQb%<9U+D1H#65d2l|nCC*%;t!4{mLe^a|3dCf%-gc)d5 zQEkMT-y2yBLJ(PkJ>5hg`O(t*6F5{3T%dSeKStu%-7kJZc>|Vkx=B`@k5Cgz zfSol28&@18hy}Ab;%Bjo0t6l4az^lG$D@mLk5gs=xTJ&K6LvYSxu9wBO%z5doY->1 zVB{Pb%-oPcDq!I(jTZ-+joD zclRTTN)`L=T55!-75%jwkTMY^A*^{K8Ps7zJ8L$K%%%1)GcZ6VUp913D8~aA%G*xT zoY>T<2rPpYan>Akh5IQSVi*j^27yx)wrck`3yBY2*tG&a0p~-*&=TN~hK*2Pk9Lvf z4<9)0@hEQ231boDq2xsZVcg02se}2|Qg{LMT!Rn|=Ag52aa!>?@z{d{Yh^W&$^C~p zTJ$ikyp5vmabs2q(|Hw~$YK;o3Zz18I(OiK=egaSDuNrBhQ>g{i5*n8_Us(NMMz?f zoaBFy)hy9R?Wbo%i748uZkh!_dwVwk=H-TLBp`}E9sHR0igT6*wnWD~y-IoE!4v&K z%MT+Zw?^ekX$NDIz*1%^qJX%ta4ACDCMjq85#G%6hESb(2P^24Xo7P-I|)I^m4_)X z(Ep(IbCK_a2141e@Z3ofjg??z34WR@NZoxvbYVR~JT|%?L}LU5VdtO)LX`KYuxNzv zrKLGzgQF3KQlel#L^|)HJ0}%lfmAF*TmDh^K84v7Y!l=WH_Bls`JlF2022~h9XDy~>k#!YP<&V}+6eu%IR02`Xu|*&t|4nb$~(q;mW^TuifVf3Hj%B4R83n?&48UPD%f@;v>{{QZ@e<%QX5Yb;dI9nmRmJ&)Fh;LdQzH;B}BJ9y*yxh_^Q)Wc%u6YTh z4^E=?fr+5SMn*VLg3llUinT{94b(b5Dt)o7WA!sCdW=yk3EQA`Uqu#zKdm%EVVI{z zNQ{DJn_zY@21ORWU6;N>2iepuCHE*4iv!()`QMnVnl+Y+ZClP&9`U|(oQ{|DKT1~J zL=|L2XKMa9ACM*{4@Yec^5g&q0m?VjpXW{Iz zy)h^jJs3Z(l(#8zoEvdeIpYl~az$~lho#v?*|EXUTkUW-L(ePC)QZj7DjsP^V}u&!ejSp#y-J+8 zmyU}j7agvR4L72qCM9ltykuecLHAcf9X_=w*Y<>L2xCUwMdU6=M*Z|e3X^Hg@!T@~ z;`L)O2O|S1+LpsH0r*z%LBBghm+`Dim6zMdBU}y9gdY4$Pih8%wS+I)Iw|tO25YN}7n4X^M)AgbOu2<2nM(oopC_hd+lY7@@4AK+Te_)VQXnoq3f;aKXK9w>tdZ zdCM9l;lYy!)H93KtL1lh@Zp7&D%3HRjGWMBnT({WU=u# zSf=NSbl`eLW4R%YPEzB`JU&<(ERCtG<8c>Lnb3c6DGK_N$g-t?N5mkPgdX!pI5klX za(={(Y@Uj+0_&u={b{3%Q>Q`v8m;Nxk0_iIj*R?M29?(0Z)o~l0%WwBA9*&W{OY^< z)WOpF^y$2*P@YsLv5(XV2fmthYro+n30#@dj<{`l@`JktiyMh0iz~Q`XcmG)H?^GP zxkurDTi9rMu?R?aV}vS&WRTj9b&kqrZKvi^7q{bm|B8gpi6^qI+JZE*qm-HkyR>@1{J9hhc24~>Wj>RbyYr76~Q(rc!sCm+#^toC7jum zH`_#gd{~#zSu?Ye?B`=2QwSjL=pReBPzz28OC3s|)jP$%VAi=13!rxFN86oj^a_@G z{2S11f*C5 zTuUl8vqkOlp)YWs`(hd6@jkf9IEw<(RZ946NM&)j%jWwHA4Y)XKa(9=QMUp36D zzGyDCwQ=NF8})YP^qWK9bM&&aPe7{POiy7nV+)>HV;e&U;%?AAob@h?n|xu$S%Cv6 zti40{{au!l9pWl3pT?ny!9q6+qcTA{ZZxlV3Je{a$CqExM#HnR348pR$0u!N3i%8} zY4D%pOnS$FxORF9x+Huwb%xF?oV9V4>3$mmxM+(y!;3_gIB9brOGUcGvyT^-iG>uY zD)eCkM)4IUx+KIVXr#?b(aTQXZJJhm=_{Bqx0I)HE?L{Y!_F~ecXv)G3R84WT$>9< zDgv{oiPM1Od!Ln8^{SkpI<<7@0Q=&@rO`j^M)<1vQ?_AMV>?C2ct*Z&~@n zyns=+4dv*?)g^8tdlQe5hP#EC`!ueN;OA%-7be@KczZa04Z>U2dA7FJJm4ZbR)pa2 zdVampk0&e4*%a{&v=0(j?gM)iTvilvhF=#?*SjtB^ei7vVaTKq^u@7Tg`uz`=JWPx z4|$g=p&`Wl@#zPQM~e5Jc?iQq%clXmoK>&I4ZNGWCG9U*o{WoBKFa*j^I*nGs5{cZ zoVt`@&1wjoQEjTAx7L;!%5Q;L^-sm<9bg;zck}d;p;RgN56wv@Q!?bsDl~VN&6f)~ zitOkd{y=|2>iu#VK^w}qbra)m3ZNBW`oHUclqO#%QX~+ z3w2^~b!TOL1L59zlaD# zz#Eom=UAU#;#oJq6{D3tr+M-4X0>IYmFCF~h4tj9RAH*&m>~x}ZsZEr-S^pspkHim z=p!L*kmLY;(CNmJe4aKop5bykPB8Va?9klZhtqBQ-ye9%iI)_@ z=pjFqbWAR%>^Na;JIrsiX^=Dze3*^4(`~k-*mGld55WyAwofO!(V?zcn(LYcweLoZ zDyz=AKdrkw@!wm2>RAgGcO1DRd6bS^+wt?!;O`F(z&^~5+y}hi$Z_zkp!X0SI@_w8 z7-@IH_^kja;lZbDX=&~4z_zH>#$lESsawY(TSp3T@T;myr}#HS>dw}F-@5@Ozzc6w z=j-gw5YM8U~!Rec?orwsud1X(gYM(e3>y@yi@Qx4^zAUwTny@voeP(oI-RC|Lv{u@cN*ONV`= zIr@L+$gNpHBH2b%`B#OY3$TuOqP9*tucn-Ug(`IZ!Hfa~@7~hg0wZ3p)w6qRkR}FV z0{RvOWn+`YS0(XYrz^KNs)=2)T(>8oIHcr_BGHIqxFz=`S`92z^v4RaT)+Fud&{Db zg+fWK;O(Ms_sN1*aD(3fD57TbghAgVf&nk+HE>-$rqyuYN<}3Be|#~@0;ORhITGIrbnv0VIUiqWN+ z+tXhrR8!Yyilh4vPb#3sfw1198di$y)74;ENhk@J$Qct0{`oZ53{&C@N|63>o(TrwE}e*#^G zO}+|O85d=lro;D@m?gTxzeZ8r%y8KipXAaP-HeI^Z$B=S6KSoi32~PZ3*E!J{gHP! z!`2F*Pdh2_iQpmWn#6FtbGOC-mKjUtASG5&%|yyVli;r9NERg+qZ-ZZrAvqxIfI7B zu=bx%+|G0iq}H_AKgh-Z1Ecj6OTNd%e}AqBxq~Xg&KRX2$MKI0L&z{u z?7>E*xR@fdJ8BCD0mI$R%PKa6nrC<&1eO!)Q7*a^EO>nBllsUuUj25*GZUXD==$kIf(5z`5W6h~$Tvk!P-p@~<*SF#LP)^EQW zxuNY$ay5CAtzm)70u;V;eqZ0FnICKI(&Z&PAWhHY;Ur%J=@_?4qS?rWiov#`Mz{$; z<<&k&ZitLBB`F#4Y@TqIlZi1l(BGsAWz33CR*VgEUMlm=73@z`xMjF`gu7MnAlwQ@ z9>5Z=ag_?+FbW#RZDr{FUeh~-7XMcq>z==&z-OX#Q=ir+tt+y7xXpofg)??^Nn zn=b?27$d6ju39)r^2hMjZcm;5f{a&KN4ox%-RO!2AUqxm7S``S_wD!ge={=JbEpdn zhiZT-3x$Ox-(K1V|6G2TXzRqyKAdw*kv8*SECws}v*ES>;i>H`cMKxpys(G$#Hls3 zu!VGW!t%M&ZS!x-*ZmRDJF_mcB94@)69^Hu5SLZ7l2!TQYvtNm>2qM=Mwn&qUz{;J zPo#<+yeiJ=3xw>{dqZE;Ge7DmZFk-$~d#-8Dx(+P4yO|%f;j6nh& zuG5F24;%AadC~DLMMqvPy>*oBPQvn6m4~d;t;3!*8xCYz*kx>%W8xr@mka-E(sOAN zA&?b3MC2JDc%zNgO!j12#L?#M>ib19mCEpp3z=;D>~Nd6GeW`8{HfM1V)o_J;z|)+ zQS$t<3(81uGhA5E$of)Kd{N5a2}oAJP`Gi0pL>=21*;Q6PYzpRs?Pi7c)Jt=ap=rq5|V|e0=!jXC|0Cc}xY&PjZ-Yn7srLqMSN*f6RQOYGAK$CDvHI z$QkF^jmw$Z*)zD)j^0vE<+j_RJ9nCOgJ_Xk%!cryu$_zhOWA$iMbZUQx3!#T$R7vd za~K(0AA$11Aou0(?`@jR8L17LJqCIZ;DtNL9n%B7*wZ6Q@C)76;p&f#C0ix1G08%Cz`a%y_F%bzNMn5xG5Xm_4Y^N1#N;+c?^3&ixc*sB^ zpfhP3bT&j)Sq>{*oi*JX+HPdc8)yZ=p}?V^HKv7~n+n7$1sBwVJxJKvr&@k>yHd`5 z?~KU*9_kKr z+@2cfmmk>6APexvafY`~64_ZKrFHd9=0&z?xzWsF&yHW)I0TgSNanijA8{(Sv-VUG zks(*wxSE%tdPp>VdW2=`*r8imKuvz|G5=Ee^-_BO!#Wj!oM-wZql2V6Dyh%00 zD1wJGfBh&kcPP+u0uQ8#3#4_%#*JZ>%uu3Y1tnt*wV>)1n~u^Hx}szj)*USKt;bVk z1{dL21H0ig`FO>FM2?73Dz6PrB@0QF+=WEn=7UqZmBWF2HNRt9eY%RJ3#ha+Q^kpd zw{OfG;;B|SrLjDlLAR_J!h=aKs)>6KRYaVbvUOaCJ^_tT=0ZO_Q(_mGZ5uC_ImOsn z2c$yILsPLZNOvd|MQpF%Ig|ZFylUR4D!Mo47wXgTZ4r}5j|m2(qjLO37jL2>)7rNE zs9KfJgEU&V@y+%(tX5j7UBXa?#$z>GvDPo$LrJS}<0J_uz()kD-wjR?;kiu3^DVzA zb?iGFCrG+AcSahGvrX0!8GTx|)Wwz4_{4KbQ>T+Q=ZU7CR+0q$?y=S*!$c8n7Pn0& zDkYRUI{%WmFt~A6jc%DU{VUS(#2VeNi0XK-BK=#phlAsp-=eCGDxv42d9E8diCGHk ze;jfRBit72D%eu^cY8@6SqSrtjQCaXEEsf>7%E?K+*@8Gp8I zcwzqtzlz7j9ft|aR>U9k-&HN2Exd%01kjFzWw`Cd$t%nrjm^9)bm`NZjQ8Z=XiMT= z&3NHQpOMR#|147!55`Y7utUgqX8>F~hloNi8ldS8>8V-i;*6^>SC*|}L=czH z+0vdO@ApO2gTGy#CUAP4K~INCOhr)g(;E|Jqq=Jd&?Qbjb1*An1(}Yum!S6r} zpw^6F_aC>9b}cmF8WEsw@uH8QI=SYQziZb?R8YRu0YaPHpI3u(BG zV9SlR|)cu6^6~<yV{+d#RQh%qu6te$4`3_bX&GIcytPhQ|o9x+bwtftFgjIZ{ zOrRE;PaO?)5_vT4MjT880|@X3WcjZ-`^NALY0%?~7nPHzeqb4x6KF3rFXRf*zVM3{vzRXzl6-U2!tS`gsRksy_}?6kjg*3~<>{c9VQ%aZ=xt<2%&em9}f* zIn)j|2NxDleFH>wf0;{qi@u~Lz}WqnM)eIN8_?V7_BU_Ge&UVyZ#kGb4`=prq;~qK zbLt4bYe^NbaGp(Ma-9Yl!kCH_>taUu8BxbK?fwNAk`wI`6mP8G1G}8DluOT-t1e^C zop&+Of~3N~3FR2m^(OGKsPs~!2QfUHCZ96BWsX*p&z>iATuc(hB-$6Ok&RySfW!$w z3iv|oTxm9iev!cMp=HZYhZNJIgY$~CR7rqz!mPZI&OQEgrDnSZj`q#3?sy14u^XU~ zvspuDja*1Y#n9pH%9o2!dtu3;)JkaOeXO^>H5^8y!9a^6S~L}vtxIr9A2`{dKz&;i zQn|!I>!Q5(Z?Bs~nq+@^?E|7oA-%6_#Nc~6D-)u@+fm~&2T6$D$e*(HNrclnnT){q zc7gPZmw9h`H;k?h9o$WYSYCOPpTw3pd>5AZQj2g$fa9fPOYPR-?I%XqC2iwWxETb* zbI(gWcRsMHRcs1eNBG`&NAldE`8Irrd{=;}v2y1U`A+DSFhrHtlHq+@T{f$n{-<^d7K&ky%YTr&B zogZgdFmW&9xg9XpL^edAQ}XktA3`dq7#bO_KaIU0idDr&F zEdaI%1Eig5e-EVi(%QSe&F7?1Z#bu?p(rGF|G3c`wL2G*jZ>w*S0U z77D*$<=Wz->|ck8&A|xLUB6jY+IsN%RM2di4N6f*-qm)2MmW9K(FGhRL8wLqe{y@v zNjbY>(%hx?o;u<5CWqg08TtwH_(Bu|nt~}}F!r_`yLH<9F#~U}CJg>i2u8adR;C~J zl5UBUE*QDaiJ#qPJ*(~$5dI$kj6ie0vD0G__pEi&J3Z!N7QI_sBzKqD;Vg5+U1o>7 z%n^5)9j-D*++}vS%S@-T9clNrQ72Iyo32(L$0G&#wqxh4$ZOw* z&6QOr6c_}n#&J{SV6kg?C6Bjj2=;Sd%cf9gXkfe0wx>SOIW~nm494)(3k5KS^HvvZ zoFh}=9621$kpejF``xke?r3viXDG`q+-O`G1TNV^$rDU$R zF3}j?ofUuwU}~qd(mXRZmJ|ZPF|m15*~zi7h!yRSIy}l@#h7CkB=Qb6<<4^U_=qX1 zOmr-A#438EP|+h+(IeiXM+y{OxMZ{75of_7&fG^b(f}mc44j*{D(+g;iDP7ll4Wd< zSbYktKAoNY@P*d#j8|x<$ZWM3xncFAPl%G$h>mp{mPYm#R8AADpysI6O|8w&B&BO zFs*hj-xMD;4=*YoqQu{Ls!$m{v3TlExu#tCu<{Xh!3&<*6)sDq5l`tVA5%V#(VyVk z4Z6a6@U}R6kB9Opc1BV8G$k`LvGXS4&=_1}z^gs@<_Vv29UZ|W*Tdk#3(&H$e)GC& zpK=3_`z$U_Wcy*J#iBmt^Bj01RAS|d6+p3@__qX;kl|)&TDi1d`4S~dO8)*MI|Hfg zEhp2Iub3ZuWKQ5#{xKO`uGN*VQPR}t@en&b#{603d21!# z{*h!$hwAVdu}lg#wX9r0i8MTdKe#wQoZvT5;WnOb%P&_k%1^ zm>Zp+Lp@Sg@)=XPl5yMTYM=65wwp+~mr8U0)4m7XI^i}xAwhRf_t0Q>=(Is*n3-j< z!!JXp4YqWKIzsJzUiSizHmy0Ps|v*8^5Gb_VLiveRwB$kyA&Q@79Quk#7^CSmlj!C zdBDoCnuUbyXeRGw4yaZ}N9PZ&dag3{Rz_eyR&?RBi!AcsrE2HHLlgt@05 zhviK^cZ3^(IScq(p>Yi{poBHz=hFfW3mc~T;v6F$n2e2x#~g))ak2wNO-*?&Ohb8! zk~;-Mz^vu~v}gA)SROIwiAmNjduZ<{RAOLhVC7kXV*@Ljo6T<{I9bL@acZuuA>d#b z4K4hY^NjoxhdBKETZel3hT7WuTe0%bP;!^M^48=iz|8)))&5yZTFqhLVO<<(aV-Ao zWkcrS0_8ano2+jkm7)9y?1Li_M27McN-jOJ4K{fnd^IP0o~7>aAm=#@*jzW1pP2@l zX*qg1l%f2BlG)zuCTB8~Us3X@cOzAgM5az5QawY^Q2qP1>R&E<;-7~ofKYb?Z#4kD;Y#YcPx%$5&G{x11viM4@d5p;X%!-r8nqa2n z25r0Fir~H)3kUx&4+q*a*E%<}0qt;h@O{;a6{`aH`9Tb=44`upvg2t){@pp}oJkFz z>pVPTS>3|RfTv6#Zw9pR%viQyx#GMTD>=|8+KuT9*~a)G+-1C6 zC3p)~NLMAW%0QYzx`7m4J>pXpFwP-?3f3{MASVN8m$G^Z=5MGv-okV0VQ=A4%gV{) zYB{n?R!KwkQSu5W&`S7^5y(`dSc|M;#JaVs*bT08TTL7f>mxyEJ9h!ytoSF;d69)3 zH|!vfJ%Sc^F5f5^%RM@VIt@>dV+!*GxmtxSiH2;h{I~r0`;LapU$`dfo21F8iDkX*X!>=!p75BK+7TPYJlMX!8u+C1(7GM5 z4sYKLIXRMbWfDw-W$Nm3vQ%AT-TK^_8jVN7iO$q8KbIpnHl6DD6hL2WL|i=1Z<=O% z?>gfn?3=KZ%yAu@cgC&b+y7gUTLIl&cbGBYI-j~uU0+TVbpzk`?aJQRWT+>BB=h)h z_(e~;+JYx}Qs_qJ9|cAB-qV;@#9AV;MpU77jQ>7p1^xH@q5nMmPEq&)rnb*G;ydo z_I7UuKRlFU7so5iU#vnO=v^(_@Q|~ic0%X3wRf}(b`A_}ZRs3@_-+u_s4w+}n2lnn zy)d3y()dj!>(d;D+DFMr13P2vZtFm5gnivAY$pm>pO6aR@Qt63*JWcG`-4);40Qk* za`yBLeq1Kgfg4n7^C^wDFwe>ZuV1{8#Z33Wb#*)YkV6amY7#o^I)F#|)E(;Sj#?i;T!W?F))DpqTv@e`T-mD zsZnwtRup#wwuX~15(B(&ym#DCN4Zjgec)5$WDh1ix12QK?S(T7W9P0&$9Hk06@Vy( z5{j=H3+2C&d&L;XYjj=38Q{mefklfC!2u%{%iz>RFNB`*`ce><-CzO~_q!FmuC(NPblmqvJ3V30 zzKH@?ERTR_-%ZJJwu#~;r-y>BYfM$J8EVWC;F4<9Y4%|(&i~ABZ&YAX)ByYOio9ya z;I}r_`kWnYsP6%u@2-%cUJ9JiRVhP#FD^Jbsv*8OlZ{P8Qx@tKUQi>K55Yj;CrG0! z*j3TuIO&$yWJ_XqcoO6z|9YxJWcHh%Fm--m1ZxuQH9w)7b$sc^{O%BbnuC+b`3;rL zvD{`yq2{-BCV&--TSAU@y_@ZDJ)rj2@NLLEp}5j+i5pNbtBv7fyyzCwIRgk5yWWfB z|0FPT%d_JeANgkKDXBy>JS;v-RI$_fhLW>zI*hSat-|M~GGddq`7JN}daD!eQ*Xc% zOiR_zdh*7Th4VV#KJ`YP_X~VU@6@(Ut?n}C7y2w7S6|pYrRvQvWH8%MSIenAeM4K@ z`|uWNpZaA|SEhbR-RnT?s*uPO>UL)O8qahKUqJ`WhUt9V>aP~x02fwxYbrhI`lyaj z4trCn1Un98tdAt{>jfJ@3iD&l>bEHA@}A^%pUhogT`A~>YX5V^X`K))cxLCrr&if@9|bEeVA(93+e&h>t?9;Q_}CswyRKy zPMfX7`aI~Z&#uGN=V9nT=29}$?|DfRf7hgW%v+WCVXE?dPmhUeJ?X7h=v`OqX>YYc zhpE;NV6>Ze{~78JVfMJP_Cu2Ap;OtNKkARYm5sdX%Kp?_*~nok`*Xak$Z;K}q5hJR zzCx3x@!j0Z39S0pl!OmI8C?y{uPwj7Ysy%5ua}{|0K6&x0!>5x4M>*5a~roy<9Cz< zORBD@mZ84nEm@4mKYB~fn!04SHD$Hl)!2F+=CbD|R73qYC94Y_%5L)Xvirt7Lw)P; z8S}f_%=ose8iKZmrWiF-maoy0$C;T!27S+cL93yuUMzW1$%{pwBFEI_mch)*zdhE_ zD!iEbiProZ`yH4I}0rFojFSC`|!)i z<+yXB7qD?tN` zjCF<6;=SDRK;gxd?i_ggH&5jYCBZ6S4g_{OxIZxg`ioTQUMovhZ$iSUTLL42%j9gJohh)zy|HnafkHUW}0GLN)FJ37b`vY8x5PJ!4? zK-~@h_mDo)3&^|44hRoHc$oAtnkX!agpSL7R9CuibbJ4W7m`I)#Hbu*eph?l$Tc3=j|ssB-Yqrh&84}Il0=QmIVI#*waC- z6D@LWb&zW#3^_u!0=c$9Q+Gfk&jciA1G$Ev5$BK-Nd!>FNC+C<1&u`#Y=!U{5I&2< z9c1da$h5^GQ^+DyG>=S_OptY)Oe6?z6o;pBt2Ib921&9Kd_1-Qj$I|-$QHq|o9q!d zRtX#i@1*l@^I+QJz+@D_biq`ZF7jf!s0gNut#)}ZUE*!sWkoPuS^|ZxC_&>s; zzn5s$cXuvcau<2v0Wx?8`SOz6pxKL1enYL|WQ;wzs<4n~hsXd?bs{l+L8uIb3^1jk zQj*FU4bA|CkwHjnPg$%XsV>*R`^c0N6 z2hx%&&QAJ2SfCRh_IBbWMLO{j3(26+r~TEBcHToC-+m|g{*ry<>FOWA&pz^8=Moz= zQ?KcViA+C3X3@_&)N8+}u?+9e=hgT}1#0{gZ;iiLq{crjP~)GwYW&NoYW!8G@oiA! z?@UqSU**;K*9B_)g15$x6shrx1(5vKi{!^eko>MV3!^U-nfAXg0mq+<;CQJ79RE`U z#~(_-@mdiae=LCwzEKp%p9GGR;Y}`x<86i`z+)}rQ6hf^ql4r9ZwN^)ye}7TpClEj z+h2;ePtuFv_-hIE@D;)FKPBLpSp>%`CE%D_1jpY>z_F+Zj#o>-vAhV5zn6gH#3DFe zD*?yGA~^n00*=-qIR04zj#G-@_*V%ywiUtgdI@7aQUu2vCE!RE!SU}B+H!Fb9B-CT zk1LDdc&h{)A1i|6KnZR6d=VUPmw@A|MQ|J}0mrwC;5bwQj(ZP}1Hh&bUM6rTHB|CQ zVd-%P7Nr0dxeylBi{-f@ShPY|3@?^n6~R(g0#%9_XtcagO?=*({GmuqDod!z--^^^ zS_wGbEP`WtaU8Nz1V>c~IHncBF{1<=vy0%UF3tnw`XV@LO2DzO2#(qka5NObQC9+v zU=bWMOTe+R2##4L;8^0=9Pfsj3PMd zOTaNy1jqama72sXII093Mf~+NPy&uUMQ|)A0mo%Ua4algoL*G~$I&I=xTXk>V@hbt z4MlJ)Dgj3kJ%k=>E?FI>E#D}DqoD*GMRXb3XyI5caHxy-QLk%SzRQ6|Er4c82~{bk z5(NuZWtkVvLq)2xyo9PeR-`H`O2F|{5gaQm9F{IKLp#}vrI=Q=ssNS%@nU(o2$t2Q z_440}kakT8WcgAlp<(O$nT{ZdZHIgS&?39F3#VS zV!GbC;$5WF6v45+1RTZm#SNtqw!R2qHVPrHTSe+ex4 zBMbf-hUfafkG`6L=h>_KwjF|J*C~sxn}p{Qzgk24_tDd@BPYshwY_9D0=6?iqk@2i z2-v{@vs47kK)_iHplNHhI_+zsEc_3Bib#*+;qNqrD{J+okCL*b`{~(~1R=z?nAGXF z>Qly48B<27Q^o+z9wl`=VlVOGathL7*st8*4GC*`!o8#d68aU0Sb9IHAhqOoG(;lg zP4YHAX)T@2p3CVf_Uxg9bQ{F`$X{s`(@`CtkZvJ+E~o3+Geo288K)_lfpmOj<_6+F zM4IfC8C;gpaZil@ZL%H$w5qDAa{dA0qh)Ur$$nPa?}u=&kuyJ`I*A-2)4W(CEW*I_ zvK1o|SGrK}lsX%?XOmelNP@tgmJ^?{g48N2$t-0R2`H;clX4tcrmQ6=D#w#nWg~e} zIhp)U36a;~`KGdoysd=j3}q9oRodum2nXT0T-i)lLAV2+A!WI>E;I}186j0L>T7AQ z*kR(MX|d}B=7I1-D|8Rvlj52;(c;>Y(p_W<$LNT_aXvtBon+12udy+^k`R{5VAGrb zt#mxizvarUjB)V3Rfx2L+AA^2HnKuFi>y+H94j$vEbsanXnmchRih=eDpsUbJ4@jA z=N7>cF9Am}-Td4Va2$TeibBU|Lg2U&D2kk9y;uY5VjPmDt|t}28hYM7^7QHO%(5p& zE!jtRxq$n~bGKPNWe|FR%+bl?tSGy`CJee8#ah zvfk>w^>jDeCuKlC?xB;!wKhV}rx!p;xN6)9`EcvlgEjObzAAh>y@V|l&k-#F&O@HA zp_lRXyk-SBQ&Vssec$zDp*zJD@VgjdK47KuEA%5~0yp?$ zR=$1olelmVBFH9Q1yK%=CSV;+O#w!~WdI_|7m2ET9q9KB;1aiyHOjY0zw&Kzw(=cv z5n#PSxs!YjFx{ctV{rhWibc-{>8BVyG4yG+T8yD`-O=GsXau$(i61KZ? zCgl%_@3o}#I(j|t0N-UW)E2<7dcCT4ty-tvOK)h_?xCOCekc8Wv+mdAd*}@yKff?T zskxKh-0#;E4*0SKP&wc$7C_^GuUP<{18%LVTME-L&L zTxn8%?XRezKiN-z0Z<=?f5pRTR?w&G{` zA!ZgOYyGr&4kq;Tgme9KLG|&^6$$4;(vOB-#<_B``}mgSHiD`G_8>q0kPms$2a3HsfoX`4R)-n zq@{J!_e-mQK4x5%=7~HG=+0wwETqa{zh&&Voc&f{YSqTzW6&80m2GIXzYHHW{%QSw z{T}J~?f!XpO3j?o^4fWI^XmLJ(F=Hs>izZDqI%Y%de)-4N1=o2S>^n7b@Nss*1cqr z0Ey94BW;8+Qa4XIXP?x`_BiZc3U37|jBVW&uXC0HayJL$d&*S->+` z1Ds$1C&2<1!S)_n04+p&#$V5km$!}r9>)OX41f~*0qIP?<_E@cj?Bciiej6tCbJKL zR4jAs3B!M2y*#7SXPFJsbdW69>5sVma0qm+x+xP|$uPkFQ5KIeuR#(*=Dbag(xqx$ zs&)!qKCjBn|H*;@^bjEC<yhF4Ec=m19GeKEV)N;`E>eC<*D61wo0Xr_?aD9c znDT3yR(?Y-P<~6VSAI{wq`X8QQT|AOsr;F~sJu-7to()kL-{K`sQiyquDl}6RQ@I% ztGp_Ol)p<`mDi+UG!H8{Y@>C{;gI>2UMSIsFiZ1I!*Sg)8+YUjohZz$~|hGyj7hk?@(vS zVRg1Vs`}*#b&hSHC_kqjE&ozIM*gk3 zNdA+0to(-BARkg26-`~N%u<&r3)JOGqq;&_s;*R4tE-d~)iugS^*H4;^>`(#HY>Z- zb;<|S^~yEs2IVGoqw*E?B;_9UWaU1!Re473P@Y#eD=(@c34_YFwM9o~zZWW7vWCltwznVD-u_S}&o&IA3{{ z+$3V>(Dz7D2+dOukjJGM!ZcZ638+7$iZlXh^E~wzf| z(EcJ_OrHkLzgGL5^d6{{PSffY%!n}Pi|Q=tQfOrv{j)laxf{yqKUA5yAS$#4+*B9s z$&gxs;}W7Xqhl43PbL&Qi_D|k`ha)rDEywK`HtN{0^;3cw#+9=L9=D1EUXvlGU>hC zdXa907ET9HM~(EpX1zwbqFF7VSE~i}YBk^LV+kcIL5=jmX03qs&69n|qkXG>}72QNM4$^l{KoNJVp{zw%Mg zp(;^MG0-4r)&`6tRJ*4!F+J28AB{1rC7;Yq$gg2oN(&$RV=ABQG4$I(ZykaqG=nr1cG=zDedY zqj)Qx?o&TRRQ1E8T)msrK_%Cy_mYk3ePmF5kes1DOk(OIa%pd`W#)O{)idRmxBO%31-@jFrKH8=SYL}1u`38 z50kah7XjuYUnLXL&2*AElsn9ML_5rR1R*hxXovJAK93;uWtgD~%!c*SUVy3O4DuK0 zD-hC%N?W9_LP)1;NHw2FY^I>=hLtbfL@M9$IRBb-i*WC(gc{&%(HB#?Px^*uZ;s~N zuc+tyngG$Qe8P}l03zH~K2{^$hECoFK2=ODeJL9^x4UObw>42_yOMoJM7x0d%seo- zmU=uRW$2*|!l0OM`<1k{FyxxabZs38Y8%K}Z6n#DolMTrHd&|cpthDDWX$q|jEOE% zfH5J#We<5F&P`sR!<`mEH;ZlK(`%&tomkf;R$Vz^%NZBl43#_8;hvmsI$cRczSC8@ z+eA;dLC2Iq%oQ-H_e=LtBHv2}_e+o9Osno(a+makaxcB1OW3*HLGEUeo)Qj%CAfHT z-&$41#ezEZCbHVE)M=}lbp`cw!*9sU*wRrYUdnV}!!{Z;Uuz>A{`}!e15(G#JAj4S`VqydWm1_gZbJ|j@1Src98UFTgjkyIvLiskqo@=(RMKE zY=rg>l6odt4bnr7X7fx(3J8kTkqnzZ6uLdmq>n_7C1ECgWNWT)$Rz;5F03XL_hbWN z5KCTJ0rY;_^kP-M4CVV_>}RWHuT@R&fyUigx?dOM{ekI`(YY5(`k@8jUM%T(3*hx) z>AKr%r5hfnl`h;^(vO8BNEco#>8ExQo=N(-m4v&oq+eQqa?@*N0xCRSE8X;C-Dg88 z-Cir*bYnea0fZat5j#(n+ij(reyqpsB;1iD{o00bN0#)04XNdj-`J2k4*8u)sH&M9 z@RFTm7Ki*%K$zQC`fuj;t*DXy(roM{di8HT{w(Q#EWzbSU++%yH#5y%TdMPzzq@n) zvrz8Wr_B9tckTm)avz*3w@eB;=w!(Rzk6R`o;KnllBYU~nFckMCAhQ)_>Oj`K`mi1 zMiq80%7(KXbTfcfWBL`#(bz^egZvoxEL8Z*ZEu4QUgUCi+IwxKzXDwj6$-$F{}J9) zOyM)%G|X(eAj&Ow;xzP&Ok)n9iW&NIYp3reC!lN20{sv{i_k^KLFH9Ggw&Wm2_JJ< zpo@~bj;0GAgCqVp?zUuYM90fZP#xyJfcj12)tKR*@hD07XVl15`{df|NVrCxDI9^d zB4>>}o4dr?Yveh3ar1awQ;j@d#LZ`2Cof=KH^WMJG%FuUUc^hT#&81<*I>9w5V*E( zI<)>ql0o1SPUu-?t7_{i_sh#=vbL^n7AQ!wUGP-^pSc&}YG-IS-$)kQk+Vc57epl2 z>t^Aj%_5vtgbTt_*G*SHPv+Fkyq>rtkHbhHF7q1I%@ke1QkT_D*KQ=$b(K(EA0#no zKf3cEz|z*4uAz#mGES)D@wG-iQFzU!)yV4vWvlH(8$_OR*0(^YllIH461k4(@?N4S zHc}kBa=SSgt9+vG#cL&w-l}QrcRJR86^5!zq?;M_?~+3T*$i)KWi|4ay+o^#yF`j= zhN_1B*0SHay4veOvD{1MIz4K&PInt1X`Y1xahf?0uP27T`cYy4V)TPo&1417G851C z*NDj35XlCIpAAyK#?*-l+og8kIGD}MgI4D9py__ity@Tskfww535ps8edYkJsSj?L zc`W?@7CE`;=-}IAvFSP6O{VAjmoS&TIxnrKlvx+mGY*jH^lfr3PdIncA+SkjmzbTp z60v30Wrsioo^@pTA^X3H^fr)z&YMe#CRl(IYef?+vd<89Y6=|prRZ=k114Y0jVg05)@2yY0f0?gHQyN|0tMk zF;c6Il1181P=VuQvvw}orj3!ET7pb!^I3tz9dv(5{nC)jlJIwa-aO?eo%=+83nHYd1^#v~NleYPU%*YPU-- zYu}d3wL9cl+CF)ic9*l56GX^9+Yp^9+Gd<9+B_R zz9&DdJu3fDdrW>o`@a0L_N4qT?J4=7_Ow!_J)_LfexS_Lo>h+4o>Nw9KUP|`pD6v> zPnC1DpD82SFO-b-E9Eln*UE>q|584uy`X$mdr`St`;GFP_FLse?IqoSv_Gq= z_KI4my{7uLf2d2e1L{icZM8!?sCH|I)N^#APUw<4sVnM*x~hIy*VG$zUA;v&)O+;` z^%=cVeNmsL{#mb5-_&chGJU3Yls-#arq9t@^|{(9@a)m&X=m&8+PFSn%j!pIlX^gV zuf9OLK|fl%PhX@xq93b0p*LvH>W$jZ^(O7t`eN;0dQf{yUkY0KGQCb;p&zZU(i`>F z09gZ}wff2W3HoXJiTZ%vtnbj*>BIU4=8D`(7ShLng)k#uev8O*H#!29X;vs;hSXLF zfgwd^su?TfC+EnEAv8-}LQa!=AylVMnz8by<-3^?RUzLje_cKeU_SXa`3rI%gev8i zO;)jgK4IINl@(q`3>e+ER)|a|CKow%PkX-=e&ey4igZ`LMo2XT`2D` z%|zpBs1Hagxvk1T%h0wI{i@eQRJ|sm>NOEnuZgH~drv;g0&sIr93N_9T)1iUchwFS&A`_>7W-d9eB!dkLjQnGz)mzl-DfK z-SOv{VACux{DxoWW?8oq@D0Ah`@%#77pQdcPfyj0xhCaeKC(QF#`seUPZ_v>|!}iZp zRyEh-sQnQx;-bwoA8aQ0Rs9w4tKpLEd`5KtJejS)`{#4BWe$I-()@M!;A!d|y54-p z@@a1Gq2|kL=-z{e_8uI7?qYhM;nMrmJiYH&Qgw*j&3#G^*~*2-9zV8y;)Dtefl_kNKezJ^bGwu$gP+39DPNfpl|5A zrAmDdRDV(m>gP+x>laAv`h`+lzet+UFP1LV-y_|qUn1?(FO}}qFOwe9-zzK>RkuYb%wMLG=a|mtX{g8Y-dt`KA5<>yFh*SY+c+l2hrvW9%oJoCy?xN2ysb9vV z{zjs4s>s&^Ram>_&q2F+Yrg=kWo?wd1QMRr6Vgo=C761`?WC-Y9>V%v0uuky9fW4( z%RqC$44@>*6#ggH@*@@pYLW+vO@|K3!-2(vI^j+Wl_Rq~FsM3I+X;d0bS{HpN0a%5 z^_cwKnwA3d4RgCJ@K6mD9wOaRrK19)mPr6)oRxf=#tTXZ{DKRv0Ltm|8LEH!QWH48o>b zQI27kDp7$Dp-T7``+fcj)DtTGmHFzyH2*YI52iIw_fNlXZI!%sM%|3Ms+(w;e|p`F zRn65*o>rrJPyMsNT>%)g%Ik&EDQ_vU^c1{s2=!HPhi`6aKaL;Cq4oOi$2VdV=CtJv*#!Akz+#J1xP` z?AC;=~$E9QS?@LSdC!|&SlhO(LQ_@ELX=#i8jI>SvfpoV1 zf7*NQ_$rF6&$PX>yOW!n+}y-Vh*Axt(9{5-h^PosMDPhHC|G&V^00vgpFX>YT@gg- z8WmJf2}MOLU_k{0K}4lluz=u;O6QxIE!kT_qCb7lKR$ls?(FW_v$Io9nK@+zzBsfJ zUmyAi-xykjZw@WOcZNR3V?%53gQ2zf(a<`*ExAvU;|N?r9+&(lU&^TiG{3EnOQEl0 zHiQnq4dg}1?dnO+_^jl-S3n-x08`0JN&}X9{sPT!bJ4@FUGv*0nhqN^zs*5oV7KPC z*{Bh^P#X)Gs0BKcJgYfx7t}*@SsV32oiy(k=yY_H=CT=*7ap#;Y*-O_e_=F zqrXCO)EuWylA~t0cyE-mRq><8fS-Vdq~WOY0mw+*_j zQGtSg!=aHeMu&Ee8D;bqhAIv|FK;TO^gJJcs23G$8}w;#LUD{a#>tZU8*w9hN+nq` z0ScYcI}@NFZcxb!T@2-hgqQq}yiZ_&e!;xrYU7=jVDE#doZsjmSYYVsz5?mh>wR#f z9GIkFH<l_=Y@25_3T&SNkYTIdO4z@5;`y(asKe5iy_;IN!5m%|;&8ZIU)$w#2#fG;Ae zRK#Z}fQ4kW#7F%FBn?kicrnAtJUI$JCTkoCiVcv%MoqfGMNzV@l6=-l9>0*s&h@3R zM&}ff`l@{?QX-We8&Xi%SWXM@WGE=APlp!h<}WIsLsfsO6IKBcb;mn5NLeTr(w#L8 z{Ter7AvK72j7N$lqfPD|dfqgMt9x{)yc;Q+0=C+Xu`1O2dX`%;?s(dv?(*k&P=Sj8 zwUd9`x%Qj?BJQz^{A(4s-mLa#VQb(Ve%pItN8%AR2;AExkB3Fc=5n(FhDOPk>Nqe; zzE;P+QLewYpeo)7DQL-ou3w19p95^QB z!$Bm@`VUfTFj8z3N^sQ1Hz6q#u{plE&GpJ}H5Z}%YBNJIUgf%~1p{T<-9cWb%EE3h zd>abXOF&w#^u z7#i|SXwD$=vjU=n$645T;3MV=k3v}yc{j&9nlir3BALQ zLm%+2XoX}iAM+E@C;TMzIq!}(@{`e5yeHbqd!uc-rEM_WDZwN(&#lWIIFnMz|83k5j;2f!HGzAAMGYwl zWWWgYl_rfGhM)tQ42Be;(xg#QvcWW@QXv4xr%|rrO-hd4i<+7Y9*#RxOY7hbaR)8$ zFgOEar!_QbYyiZ0zvTMv`=v}E9K4eMI|&)uY4cqL2zHWoD<6^74PKE|m!gczksV^Y zR%6Kml#3EX1Su4ZB%@rX&!MvFiWA>l{5JGRT;rx0YB!u_dPap&nk7}g60HQTlfT-? zP!eqS8jX5kUgy(TA8$_6Qb&7YQU!6er?@KJhdlNgr}JrE#lbCcT5TDZ2Q06voH{KJ zNZzMpVDo$;1qr}4CL3sNPZn$&qu?J+zEHzU4C0W zw4{e=v27%TT;3+X*EeIlnZ{i+#+$W}h~X4CT5~x91EE-VH1%w)oqLj_x%XseQQgdk zIree#BG81^b~=OFu5g5N67J@DT|(>8e5Xrj6Inrd4Hr5)BdIQ+w7~PDq{;rBEXkiU z#ho*hXc*@@fa0~j$E4wz#d)rp&J*+q=R%Y=tl35?Wuqg}P>D7UtSm%n)4G@~A?B>K zCz>rK*$rg`%$UN}wk%=C^d&RliZXqP#4@z$OC-VcCG42KMB=tK>5Nqyp3tD#ldX-_ zV;TP41n(+Q?Oo;CGDUnqu5Cz+1Pdo+#H23xFAF6beH{2Tz0pUC+muu_=mB`s*C+Qw zJ5Q&-Rw=(Y$i9-aRkeMO9QE|R#GUyRSZ7~e3d&Mk;kQ7D-zs_8?a+YV0j>F+a2y{4 z{rFvQ4j&7b^Sj|@eh)mv$4QfP9gnuoqlSm^77h2F|5F7#GjaUnfYK0$S

RM<#la0+=Z*-@bDTTmh`z_! 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

os=%(6-TUNPOLg?y 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

h2tb)@i9+Swg@FGhd|T^f;`AO>`aVkP?V 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

uHx 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%0A7wWctaY#7&vCE-$0`n5JFa&T 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�D1h$yEMM}~B(+^`q*o-!+Qa>cF;mpx3HNta% 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%0Apz9WsMP-fX_|rTl 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

6d>sr1^T6)amXXC1dd~$e9!dn9WZn|i5 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

Vxu*%}`b?=p0vlxIZaGe_G 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 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r O3>YwAz<>b*>wy4$E;Nz= literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl b/java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl new file mode 100644 index 0000000000000000000000000000000000000000..c23d2871bf135b162dee70f3081b449e95be1c11 GIT binary patch literal 48 hcmZQzU}#`qVBiE|7~ldj_!y+0J%$Ou=vNL~)B#Co1d9Lw literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 0000000..2bdad06 --- /dev/null +++ b/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,8 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE TO STORE *** +# *** USER AND SYSTEM DATA. EDITING, ADDING, OR DELETING FILES IN THIS *** +# *** DIRECTORY WILL CORRUPT THE ASSOCIATED DERBY DATABASE AND MAKE *** +# *** IT NON-RECOVERABLE. *** +# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c10.dat b/java/lance-namespace-hive3/metastore_db/seg0/c10.dat new file mode 100644 index 0000000000000000000000000000000000000000..3e1aec63554501fdcd0defe3f4e6eb6fbba30fa9 GIT binary patch literal 8192 zcmeI1J4*vW5XWbakatLmsPWw?2nH3jkQBx{Bs}Z6TF11cY3B{A=?GJ{ zE+K)j5xrF0-rGNLUq*`v5CI}U1c(3;AOb{y2oM1xKm>@u-v}@b3OL1P0l$938xExa VPoCX_U9`_Uy8x?x)%U|H{|2MJW19c~ literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c101.dat b/java/lance-namespace-hive3/metastore_db/seg0/c101.dat new file mode 100644 index 0000000000000000000000000000000000000000..1118178122878d154f3dc957aedb0924bf7933a6 GIT binary patch literal 8192 zcmeI0F%H5o3`Ok@ZAT_%Hb$73I0Itl2+V-Qf>;7 z7b%YO?ZnF4Vp)lZ+AK!mZ0c-mLOj;Yf0m;mf80(jvap$pbV8C^aoc|#t>urSThE`0 z?s7u^YKsn|B0jHXUCn%3)7U@&0uX=z1Rwwb2tWV=5P$##{*l1`uvS^x%fbgcabEWJ z)(~$7(#%>0JISj?K&w}s3jchSfnL0-;p(FGQ1k*OGAr}%PO+xMsT5cs009U<00Izz Y00bZa0SG_<0ucC}z*y!!dGqL=Uo0^$Z~y=R literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c111.dat b/java/lance-namespace-hive3/metastore_db/seg0/c111.dat new file mode 100644 index 0000000000000000000000000000000000000000..71b1f8d3f96f1adb7b0cd89180dd4c7c8814d408 GIT binary patch literal 8192 zcmeI$D-Oay5P;#?Hfby21~@Dj5)up-AQ%j1KmrL4gX9F{!tn_B#13R*- z^zE)8Ur!{d{xaA}R{RKPToq4+?|dVDb9PbF_SsnHy!=ciGWW5EjfuopA7DZN0R#|0 a009ILKmY**5I_KdUj;_8a7Qnv;rIoJ;V!rU literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c121.dat b/java/lance-namespace-hive3/metastore_db/seg0/c121.dat new file mode 100644 index 0000000000000000000000000000000000000000..fbf18b9c97f9d8c1268253438a612ab37daf5f8b GIT binary patch literal 8192 zcmeI$Jrcn{6u|MfDUy_qK&7NoIfGHC96^m4okporx`EaOoI>LQbZ)@gugr=tYV+Tj z?8ke%d6Qq4m8FOneQe8IpSwQoVm^)O{1I9${Bb$f%v_&Rq!l+AEw1aYt+D)JaBKTh z$-7*jd)2}8lOlfKOYdry>z5b{1Q0*~0R#|0009ILKmY**{!w7NUm02Gm&G6K%*~3o zZ;knSA}{pHU?XL95zsiRPR0LxBRzBWQPT-od-Y(;k7ODmcO7lv>=XhF2q1s}0tg_0 Y00IagfB*srAn?1uP-cGfWj8rK0W4ZBr2qf` literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c130.dat b/java/lance-namespace-hive3/metastore_db/seg0/c130.dat new file mode 100644 index 0000000000000000000000000000000000000000..7b2a6548baada97b880355f2e256c0229b1eeec6 GIT binary patch literal 8192 zcmeI$F%E(-6oBDZLa+k^n~90Daq|G4fw&s3fhKNVz!P`@@8c!hoSgMhcuFb`PA29r zp_KQUKKgA%wj$#6ZdwxhEcE@(^8J{O?_G<+A759RsoQK}lX5NY?d6;2)vv2)t?n~t z7md4x$g{}6x}m1u4`c`-fB*srAb^O2lK%zz8 zQZDwL6DO~;Wg{YLSJ4s|Qy1e9>T%Bc&$2brABS_RtnA7~x?z&q;x_);T9-eK9zFk5 z^e&g^-|eQuXc0fJ7Tucpu9jnf00IagfB*srAbfc-x z7T2XnQ>5oyU(=m>GK3I7009ILKmY**5I_I{1Q7Tyfy?!%vbQ^h_kH4LgST6Te3VEt w+dtJ?8`koPpUPT?zPAZx2q1s}0tg_000IagfB*srAn;p(mCUPx=lg8(0!6?R4FCWD literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c161.dat b/java/lance-namespace-hive3/metastore_db/seg0/c161.dat new file mode 100644 index 0000000000000000000000000000000000000000..90960e6d4a00549e71d007bcbb2ef09b92b2e39c GIT binary patch literal 8192 zcmeI$yA8rH5P;!xiXCKFiCVpQdx}N2skz;`X0tg_000IagfB*srAb`L>3Y^Y+BOCp)_=BCfS@HI* zvEDA^g&r9krK}GEI%oA$@ju_l(A<62EJM{EJ=peBS%iu`EwGKVt4|OSKmY**5I_I{ X1Q0*~0R#|0;0J+;to-h3cbmTed?PMZ literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c171.dat b/java/lance-namespace-hive3/metastore_db/seg0/c171.dat new file mode 100644 index 0000000000000000000000000000000000000000..55d40959a493d5ee3bf7cd04992bfc655896f7ef GIT binary patch literal 8192 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 R5I8^edt$hmXW#y{{|7={7a;%u literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c191.dat b/java/lance-namespace-hive3/metastore_db/seg0/c191.dat new file mode 100644 index 0000000000000000000000000000000000000000..5e31e3bed2c2e5d2b5cdc59498a27d8fabc5ae3a GIT binary patch literal 16384 zcmeI2U5F%C703VmS=C=Ny|dpR*(94yHZe}pyOZ6W-6T5I)pvR;Q{7dms@~n%T`k=t z`=C#vSr9=YevrqAFY23w1bh=geG)}b5CVb^K|}vlw z)ZAP3yXTyH?#DURxDTK}U;dP3S(W8%F=?Nzqw9Z)s5OGI773I2OmXZ$hGPgi( zf!qSQ1#%1I7RW7-TOhYUZh_naxdn0y{O?=f2Z%_C7x4K+mFWF*|Co#aZ{bO5*4s6Z>I>w}u8 zC!o<_I7PJ3&_}efLWpfI5Ke!%BX$+0XrQT&;minOMngMtyrFLe)0#KIHO z6jH^CJ|xkqFQRDI7tV0oo7lHl!|Gl!G)e<2*qt>_p^mmbCK+!(@NCf=1%d`%sa0s= zfIesyEwZu#O(`bU^eM?$g}$&Ii@k8xd5R_u>XQxz^KQNv+IOi2;a;r*I;LI3uJ)HgHuRNvqNr>55@L zx~2qc;(2`vE!tyBIO;BF*uo3?ps_fih^7>2`4zmVPoZs*#fbviV#y&`Cka`_NAw}& zQ{7CTYU88&B=RXHW%$$qY;EbYPT&}`7M!ZP8zsjgb^xP_ElZzBPL)Dja4N&VR#%@% z!#HNndzE2g%ht!xIF2#%3f8dI+cSlHN>SJwj5@Z&o+*nyWi*x!?RiCRf!qSR7O1{Q z@10S-jn4p;5AZ1}-=_D_sKn?|c?veYg#Ha*m%oWEDzBqUWdl3(+WO}lGnc-Am#DnR z*TuiUq4FK{sr>b~8hSAaixww*& z704uVSSEj5Ac?Vzhj^Rk{jWqJfxc`PiiY}`d$#lFONj9%j&X(<+O}JCh9ECETbrv=#t)EEN({Ilw+BoE47q7 zLMD1qN;N1_%4$k3ArrMIr9@>)X{O{CGSMnf+YW@dC6@hgH6_WANqYz<6LZpmOrc^* zI{5T!7db@IBO56x2R$YoVIzkUXme=;$!w)0A2OLrYnF3FKgEeH+a_n{k!D)8nv#Ub zq^a5G45UBKrU=VvIfzWs<9IBw-wY`kXO5MY{4p&%k;zv6IA+iLqnVYcNQ>_2H&1h7 z&iG@hob{{>MjBj2#Lh5DLfEM*5p8)HIgJNGDeCa7UK|R06gbgt?0c?btHq%W-IG4CGS~#;08n0*zG+xn+6+EU-Q@Zl#j%guTZlGR$7^^tD58jM) zQ=XKsjmPzQYQ;@bT+#t2qiR<1gg!}~cj&A`y82ca-tdB+f*Clc4^u-*2}oy~7MDeu zi6`}G2e6tJi*nf zvvFB|y-y36_u*4S{cA33ceylw!O_0)6puozRhLxXWUwHxxV-TlZ)>%r??}pA@c%fq-=l0HR}C~d}rai^oxGfi!#e_hh;9T V$(aAAoC~1*!d(1s{rKHK{0C_JjD`RJ literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat new file mode 100644 index 0000000000000000000000000000000000000000..cbe66c52ac7e3472a5d13d35344650aa6025d2ed GIT binary patch literal 16384 zcmeI3OK%-D6vxlZ+-uK$CIuRvr94X7l!kg<9uHI^t1h9ug2Zl~e1Vd6H{=U|B32+a z*|X^yv8dE9kdIKYN9qCz!5P~(4{nk}mqfl&PA2xx9?yU58UIgjVFv&_{OLaf9hr{D z!=nCp86N*_KmRH|^Ur%&b02>~fYk-$;mPsub3b34R{PyX+?n!Yed&VhzvHh!n3MRY zwZ$@h&hWt*wXWDH;1qBQI0c*nP64NYQ@|-!zlYu~ z_cs0HXHkE$6b1}!v=6%w9%cegJ+jS?jJ^lAy#rI~{cLOdGxy1WkKij?^FWsX_`l-8 zB1hoE*2e*?!?nEYgb+$>im0eI^SEg@MOVp9EEFP7Who;C0kFwo(*V11AE$s*z$xGq za0)mDoB~b(r+`zyDc}@v3S4{zet{40BJXI=j|U(Ab>*iM{{KGQ#NyAFggC?h1LJ7_ zzddgMZPVb;bRU`iBM*-*pZmRs7b2|$`gg*^`y4{U$D$RYpgcccfsx^}EE7Uf{Rb;B zHhdoCm^`5P;S?r@SFub*6cgk3Mldye5fzxTp!(+_%naYAWh!#2|G^CAnvdcP$5T*z z$Y90rDr=R9YGVBU7*-8mM^cH5)( z$xq=0!)L0fg`{}QYh5;co+Y)&DV{M{GklRXwNMn#$MB-z>ompjW9I7I9G1TVFB!h8 z1dfN|*$7_Ne9|PizN8}h59aWS=2MZRI3F^C_oncwi}OuV{Rb1c zVt83%hA*f1VF<4qUKKds6veYuxN7)DcBzmhalOGRyrKClN~%;SisvJE)9@(AB5?qfFCT-81|K1F47`|xnd8nxV`5ZP3-&VLDbE^O02ySXVuk#ew3-x{p z7$%{0gS4!1!4%Yl3rDbZ&zvD{@rny-MBx~=KG6+CmEjUDs8>cfgRM_>gSaa38Hy?K z^EC}uVCyr}AgOUt7SuyJJp7v7()Pd=I0c*nP64NYQ{exk0B3;T66aq-1i%jZW45p3 zj*fSATo?%m|Cb^zalf8W`j4&uFC%ngLQ(zmiS_?wTGi;!ss4k7|1YJKxWA|P zA+!F!R2lkbMe%HI{eM~Jc)bP1hur%AvT2Z)ls_MgtpBf~8pp3Fp3kiRuT+Zptcdd4 zKC}M6YCFs~&(NUdK92I|erWxFU6kmz71ckVTK`{nNrwKG>VG)1{=cak)KgOaJQ!R5---nD z5m8R)@6E0MZ}C}$d+6a>K#Y`u|Q;n2%Ew&n{X2->C?n=Mm-SJ#PJf*GBk!&MAH{fp_)$sI3IvuY$VX za00h9UndE!--23?;S@GC-y{m}S3%9Ua1QU8{;Lk>TS3j|(enTBTYBZY0;hmez$xGq za0*;(1xyxT+5e-TNB_+3>bTa&v$6nuPuH&Zkw5CA$q1a43*en*SRa=&0%zp{{!13% M+5G?D@^9P!0BGrK(EtDd literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat new file mode 100644 index 0000000000000000000000000000000000000000..ae654971565c9fba795a5270251b9a46af8f4c65 GIT binary patch literal 16384 zcmeI2zmFS59L1k^*R!*`{*`e2Izkd4YA|xava=BbV4FMs9 z(m)v@pyCfe2&F+#q6kHzprSz$qN1cg2+>f&ys>@foX6nhTOguY$Qc`3xN|%%j z6&a;RN(EIJWtEgFYBCBh)|6_f%P4(A2^1PK%7By@dqk8~)^4D&S4Ls&1_^GFQCPb{ ziX|C^wHsu(RYWl}Jw#dIHW`IuRE}}Gh%(@JQ5tv1DEuxe!JQIHFK4}|6w5Odd(pGM z*hSAZ&ZDq~yJQsl64tR#MxifZ19!VAi(ba%u`Z}!zl_3TT~NgV8HLBXpoZf!lme?- zFXxnRx8xx8>{bFU8CyXtbWGV>rJcssqqh1Kd^d= zTHdg_j~ZRK`o7iYtVY!Es?|5GwyD7{RzI=&iq&Om>3ge}tv+itpyDg57p<=2_-NlR zU%PVkhWvjFM@>(A)H|jBl>f&s4IEbj7S8|w>L>h}1)>mzYjDtTd60vC_IA(RhQ%NX}aDCQq-W{=_u?v+vKOI*c$G75c(Yd9pM z(3iN5`(+fHxEnYuqj0s?3M(Q?n{!&nctA$soYopgWE9S6o!~(kg>zb`ct}QJ?dl9i zWfaz~uAnKSuy%D756dX5U0uU58HKg0>&RskTe}UkL=^L<+7OAFN(cU-ci?~HK=wN` uaCXJ&meqsQ^hc{7Sv_r4Q>5t3OD$A-0<9P3_pmW_xQUDh(^bLUeR^QorsGgwRhxSeZerK=R_$3sS&>;9{Cwm(lE17DT= z%L&7~e#|&&;?Fg_>sjs^8XE{e00Izz00bZa0SG_<0uX?}KN2_`w?@`_v-rTyTvWW> zHRjuiywH)sUdnn9&>7WL@ttpEWNuzHRmj@WgPjG;WDzn~r|3|^1{ee&009U<00Izz X00bZa0SG_<0>2TM%F-89r%Uez@u)7| literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat new file mode 100644 index 0000000000000000000000000000000000000000..761408d3b3483e2cb3bc4d3d46e37c5e92d2a255 GIT binary patch literal 8192 zcmeI#u?@m75J1s8gMx)9XsIY^8GsoOEn*EoqGJIjUU*)|)wt@6|}sAD0WOtjp>!ZW>r~9~a-eZ+^K-&Z<6h zQdnN6BCjSb=Z2ns-%=rk00IagfB*srAb<{9 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat new file mode 100644 index 0000000000000000000000000000000000000000..78d701f45559f9fc67104563ad350118d55c794e GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c200.dat b/java/lance-namespace-hive3/metastore_db/seg0/c200.dat new file mode 100644 index 0000000000000000000000000000000000000000..c3a7808dd76bce2cfa24ab40d4e9e5d87dc76d32 GIT binary patch literal 8192 zcmeI$u?@m75J1s$1i=Lb3s50M%K*%PXb~gO0uod#zy$2W0xUtt2yk3-Nn}DnLxH}d zIQE_8i(i+>PDFysP}eC&nJma vuIq>4T8HfiLRaS1Ri_vsfB*srAb95yH6u_15*-aC4FwGwFa=XE155#DJC2+XkZ936 z$>;moC%?`o8xb+OoLH|juTvHCX-w^BDUI+)cdnV0u0o^}i;Ol`|EsjNzf2yza4NaW z2l{v2%qVFR>T25eEOxaR4g??o0SG_<0uX=z1Rwwb2teQ;2^`K_BWrzG{9s#eYevS+!R9<8rQYf;t#g zG2c#Pxn3FUrKm3gI%oA;@ju_l$Xr9z4yvrXdT`}uvZyld;R@Tco6!(J009ILKmY** W5I_I{1Q0;rCxNLf!~V;?yuASIbS~8Z literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c230.dat b/java/lance-namespace-hive3/metastore_db/seg0/c230.dat new file mode 100644 index 0000000000000000000000000000000000000000..624a5e8baa86d23af2fe1d95d9315f64ec0a33a9 GIT binary patch literal 245760 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 Lz_B8L^8fz_ikqu^ literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c241.dat b/java/lance-namespace-hive3/metastore_db/seg0/c241.dat new file mode 100644 index 0000000000000000000000000000000000000000..743806b6ddfcd62827528081f864037bf8996df6 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c260.dat b/java/lance-namespace-hive3/metastore_db/seg0/c260.dat new file mode 100644 index 0000000000000000000000000000000000000000..25f81fde784105363c372eba91f6175388235f63 GIT binary patch literal 8192 zcmeI#u@b>R5P;#mn}{nEdX-A+0X&0YhQeq(1ZH$RfG6-+YQ4@Qur682oG3I3^Is;H z&F;-@?&~635pjAyhmUg}=lW#zdQRheIg<3p*NIlvMYU^-I@&zg%Qw$kSS*vh%Fi5J zHSdNZuO#5CmTJJ{onf-wck!@^`wyH wy1wVmRobsK&Sb3DTxM0C2mu5TKmY**5I_I{1Q0*~0R(<5Fp_@J@zR0f6#Y9cqTpT@tH{d|bj(Q4xw3HM?<81yW zJlgjPFMJ!7gNPWtsu9_k*cb+14|6(y)}xdDxLjyur&lI2@SBV_*Y(%Y+rF4RM((NL zT{bbk>&;ApCT?FV+Md~|m1BVb0tg_000IagfB*srAb`L>3S6#7BYXWa|AQUbS^D;^ zzTPb)sU8`eC2I}>dS}g3{y*Qy)RZn8ZR={R_p1F;=CZ15Ynu~^Z!SSZ009ILKmY** W5I_I{1Q0*~fu99(*|@z$K1^TR&n;~L literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c281.dat b/java/lance-namespace-hive3/metastore_db/seg0/c281.dat new file mode 100644 index 0000000000000000000000000000000000000000..cfed875dfceab65004fe1b91cbefd660cea0ccb7 GIT binary patch literal 8192 zcmeI$Ar8VY6oBE^iER>v#vwtWI0HeW&}bmRfk1KsZonnr0Ml>(Y%uf+c^G zy|wRkYxcQ4S&N9#%Z|jw)WtZ2dYsewvmA}|$K_NjOTBWDPS|Aha9w{Lt;e56kDh-j zdY4P|?|L)C=n%iJ7TuZoww7ao00IagfB*srAb{RQS&~GB8)4O?G9~wjOLRU?Q`!GItqmN?d$`hyVfzAbchAM`1#m1bdH?_b literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c290.dat b/java/lance-namespace-hive3/metastore_db/seg0/c290.dat new file mode 100644 index 0000000000000000000000000000000000000000..a85589e545d81d6ae0a080bcb44ba28d846f9987 GIT binary patch literal 8192 zcmeI#F$%&k6oBEEAT@}CcmX$E-CXntic1Ia8Y;MX0YT{KvAlqz(81YBpJ`)Dt%HM$ z{0T{u_tK>Kw#r6CjJ9X7zK?ug?n1sC)A2nomGH;uTr;aI+X;)>dbkUdZ=P4TSXTDR zKXY)=xEYGP4yoDKpXqir8A1pkfB*srAbwe_@>s%c3oQ?0Sqw0MUR0tg_000IagfB*srAbd`` MER$^4q<=d<0Mo1*Jpcdz literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat new file mode 100644 index 0000000000000000000000000000000000000000..8e2ed6afe90b6e9bab82029f98a338a3cf455bf8 GIT binary patch literal 8192 zcmeI$yA8rH5P;#cizFp%Kt~A`6*C}eBo?3sBr0eqk?5&tnSv>p0j7Y9ACVIR5-s{I z%49v}E?KxD-)~u`K-V?%Zx)KyfWW literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat new file mode 100644 index 0000000000000000000000000000000000000000..2a2969247718ad8c76b895d72b43a1f781e3cbd9 GIT binary patch literal 8192 zcmeI$p$@_@5P;$9mTZ$e0uBoXg~t&L2Ez*=fdq#^F2VB#I9>*g1jie|tzDOH41y+q zlik|8ZkK&-m5qoPy^0apnAjKwUk`ISf0m<>{?NxX0$OL)Q~p2S$iQ4&HaeHpSnoyqnM`C})($o&5?@_{hyVfzAbbTe~jZ7z9oJ zP1cXQc9;F!Dk~8&`s6LLePa8t^Z78Q^Jmd&;g8FSW)}KnA}znkXmMSCZH?uR!&}## z3f^S{y{itU9~5!>D!r|lZ7MMq2q1s}0tg_000IagfB*sr{G-6`ur{*PFY`axk)5S) z-|F-AM3U;2!B(>JBA{_rp7Q_sMh52WqS2|y#yZAYek>iC7P-BS`ISU`aRGV+5I_I{ a1Q0*~0R#|0009IL_*q~ibGNsBpFLh?bT1nK literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat new file mode 100644 index 0000000000000000000000000000000000000000..4adc6e4470f86182da42ea94fe6881290c97948a GIT binary patch literal 8192 zcmeI#F$%&k6oBEEAT<;RZ{Q#zZXTdlP`ZlOP{GX$cmgjaNLOb!2M?gnw6P`D!No!T zl)k3#g}mn5DjN|odOwHtG4Zh(LcN*O`MnxZ`r~V^l~q~ohebVY?!wDA&#PN3qrIxn z9A7kVrXsH@rJ7uUx zg-)XDhvrnL?NR4W=KdOJoJnrdy3Py%1Q0*~0R#|0009ILKmY**ek72|r0jG%7o!J8 Ck`^og literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat new file mode 100644 index 0000000000000000000000000000000000000000..b37b9b254234c4de527ff90f13f4624bfa8f98c3 GIT binary patch literal 8192 zcmeI$Ar8VY6oBE^E!ieH0*(X)2E`c&nlm7Q1cyO#0ult0)1YQB;NTSS)~-u820@d* z%U;{}x;6XUDk~8&dKWFSF|jcWz8>au{484|{c$?g%0ll90R#|0 a009ILKmY**5I_Kdp9RJ;cWW<){_zC{d@qgw literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat new file mode 100644 index 0000000000000000000000000000000000000000..d854b4b482d64363d5e58c63e9e4d8e5633ff2ec GIT binary patch literal 8192 zcmeI%F$%&k6vpu{R%!(Y7eR1yarFS6LEOX}cmNgLynu_2p1{Ssh?j8m2Kr1JTWY&H z$Uo3Dc`wZ)zpbq{lAK-d*6@Ao`(hXJ#h8tsSu2HWr!&i}(rh;@>R9n4Olt0x<(HR3 zzqD7jZgjV}8%v)e75n;{$*v+p2mu5TKmY**5I_I{1Q0*~f&UWNpSDhGJ5zYUj{FyZ z@7M8=FCD)b+mk(a%fpR_-)$f}$Mf(7jh+<3 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c300.dat b/java/lance-namespace-hive3/metastore_db/seg0/c300.dat new file mode 100644 index 0000000000000000000000000000000000000000..2053e0105b40818ea4cc1ea3a6c1cb5edb9972df GIT binary patch literal 8192 zcmeI#u?@m75J1s$K*2&3Y>^6y0a$=0qM<`c2CTypbc_HOCr5$_1qBWI zw&I-cEIWQ(WGf<0pQ0sUOvBh5tlrFNe6L!R{y3d!WnET>wrHS-dz*aozWK#6+N=7^ z?5cS;7I_}hvTr!k?^`OQ5I_I{1Q0*~0R#|0009IL_%DIOY3F34ce4NcBt*TpTUtFT zbW>fQxl5hy6k%U-nQPBqdcBAU0R#|0009ILKmY**5I_I{1b#0tkx_Zb>Nq_=05p*m AuK)l5 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c31.dat b/java/lance-namespace-hive3/metastore_db/seg0/c31.dat new file mode 100644 index 0000000000000000000000000000000000000000..7ed780bf8a4ce088bb41bbc28d9a2e589f1131f6 GIT binary patch literal 8192 zcmeI1JChql5XW26Y4two3>;uy2F#g<7tic-1`HOj!^YquazM7P3CN(p5h)d;zD>-78rmowQp;M%C_>{u<5xdZwqRXJ(~?TL93)7hP>uht-zl zeY+0J|17SJ>YX1y$2;HPs}C?+LM`kZKUZE?x81#SuRkd3t+u%0!e98-5>_W$?77dn zji7|iE#4D#{1_(8N6OckknF#9J>_XPH(8G66rVuKpp4H1_U-m-G{V_ak^L6>zp1@g)59;!>y${dWeBJtOPvKdcuZ`yno?{+!-^V?I5CUc8CS7a{M5ohiJwoyYvijdi{(_!+#uozL7zq!cci-&Oku@Wv_L zcMH$++{BM5y%&6Wes#{k#a(<_#I&5(_&o>QUA)$Oe5~_5c$4|{^^yrMbOR-p?c;gj zaeVgraH)c)?Sk50@dFSQytN(|?GHg#@U&g8w?6`JlP`SN7+mjuoYD5E3qSGGuqgc> zgU`HBUKEti56DLmK1qa$KFv=c*lZuOAWUOS>Z0I$K$oOenNs+?v9}Ll$*T~LScwix zfwNlp+D%nK#~)o%7<>^wg@}12JdA+Egp?w411~DvEYzGoWMF6lh@U~syipQIBr%_f zPcwxlN5tD**}hIv_U8Z;^FjnE`B~#n*8$CZtl~@vN|;LjyFGY|`AjFc-zuEY(*FeW zxsY_6@nxdekU!l%yv_Xjcz62W9l&MgBM}D}Puw4>{TaeLr9UDHm5}UDMf|%Xc$fJ= zm{ ze^|P-O6sZ}@VmhLqtc~Bdzn$xgC{YeP2y&W;awMl8u&#lDJz^l%#TZ#QarY!l|i9h zjnAr!G+G%9VE%DwP$ZEt35At=C?eO>D4cax4?~z=WrHxw!Z5<^e`OF90dKr(E{$M* z?bH}>laSOy7A`X*h|@6OF^pmU2^(l71s>nrL+D}>;p`;|oji0&t#!c$m>So&j{!F@ zPn{kErpBk6J@|nugCul~EFbPMswR>~Q))Pv8lUYlNFuS=T`Yq~|3Ag=S^xPOoB;mE zbr_M3&jNm}8yr)4^aGWL_ozHLB<EV7<$FoAoB^ z5ozlo>m63Z8nHU0aG&*rw8u=3nch9FVa8#m$5xXmjc$CMbo2|4l$r6*RGxgrcfTWT oaSNlrnc<u1>-;g8#yW>(rWk*+^vw7BlSw$}3J(Y^1U z3f^S{gPTq!4~n>Rwb9nhcC{EA1Q0*~0R#|0009ILKmY**{!!p?+!|Tym-!#;$gVnX z-|F+tMB33SgS}+cML_GSddmOj8yT9bi^jb&o9G;C`MFHBFUo8&#oCjH3os&p00Iag afB*srAbVZcRFqIrAO@g9)UwmeL4+bQhZ0=*mU9p~z@+^}kAM`^)&z^QWS_ zTwrk5&5WWZzOJTS&-_q};XnWa5P$##AOHafKmY;|fB*#kk-+J^H?q~2g%5V(tnBTr zA>T}-nT`yOl2?O(R;xM{{`p3R=IW!JewnqS2RjRx%d*Va%{ER7YatMT00bZa0SG_< X0uX=z1Rwwb2>e7~Dr;YVTTNy!_+>2u literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c331.dat b/java/lance-namespace-hive3/metastore_db/seg0/c331.dat new file mode 100644 index 0000000000000000000000000000000000000000..85ee72b31368516c6de9fbe3516e0e3229ea2755 GIT binary patch literal 8192 zcmeI$u?@m75J1s$kdl;)Kt~BQRLp=V5hG9o5*-bqVgfc`3T8;b1Qaj@ob5PrLO`NL z-;y2s&dJHIi)AAsM!Ri^8&fyNL&(Q5oj=Rg2!CA8G_%s4i*&;#qs4XowY8Q%j~_k% zR`e|w=->5WhEWl}uQs}x`K}gYfdB#sAbHq)$ literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c340.dat b/java/lance-namespace-hive3/metastore_db/seg0/c340.dat new file mode 100644 index 0000000000000000000000000000000000000000..d99b11a3f2dfe2333989898bca9463dfb265ef5f GIT binary patch literal 8192 zcmeI#u?@m75J1s$K*mB8Y(Rx*8GwQbEE)>L8i0goSb&C>ozfsN105s4;lv~|p`f8a z-%*^)o#l&P7ukr2(fc{FFxxQKr&zD&G`^Q3Nq>BuX=PPZ`*BfEo4fe(&GY6K%Ve+e zGe=j=o3Y5NNyEOOr`tDFNFjg#0tg_000IagfB*srAn;!Thtt-`TF(^!@3Rnf-cA|o zNuh0Z{lJ{7bZe@y6)$tWym-^CYD5SifB*srAb%c`MXo7z5=i5{uUv--&9MZ&vF5D`EC d0R#|0009ILKmY**5J2E3fuStizH|39egYK>F4O=3 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c361.dat b/java/lance-namespace-hive3/metastore_db/seg0/c361.dat new file mode 100644 index 0000000000000000000000000000000000000000..b5c8f259d0d1fefc112f60325bfde24724aded2e GIT binary patch literal 8192 zcmeI$u?@m75J1s$kdl;$3Fs)HqM~2|L`_Fa4M=n}luW<|Ou-be0fLqV;B3c{69N(~ z`j&FB@0?h9T~5{_V)U{jaWQo<4xt|Bbp9+xE&Xvh)yh(@T%;W~89iLrUq|Ed$Kk!} zpNih)61|(=%pf|%@2f<2X1=ZDSRjA^0tg_000IagfB*srAn=a@`@_b_O1~`pU?*;t zy?tw_*9&Q;ErXrpWh0<*Rz4N}^NsY)*=JkxqH0?YwihswSy36gj5Z}sK0!nP0R#|0 a009ILKmY**5I_Kd9|T6S@Vl>_%i{&Jf-Z#s literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c371.dat b/java/lance-namespace-hive3/metastore_db/seg0/c371.dat new file mode 100644 index 0000000000000000000000000000000000000000..ad11f01b25b6bd995142e4d731203e66b5792409 GIT binary patch literal 8192 zcmeI$u?@m75J1s$kdn|b0v)1)ii&~>5H%AZIwU}%qoHI1HedoureFq`0?u|EIUyj? zqHie|`!3EYuZv|XB1SJe5*Je!;}Gg`PUp{J)Y2c9Gp(%k%0)WiA*0Q8{dF|9KaU<= zzbkr|OZ4t~GsCEff36Z;&wO9Wu|NO;1Q0*~0R#|0009ILK;Rz*j;EcGjec49!A{&P zd;8Wiymj?ljvvODX&o?qKH=k{-imE+&uQNLF=_GAyFYfN*B?k-~k{H zkXNBcJOCYU0poF;L}9ZeC1`BjckB6cpXX=$q&xTk013VNZG&~ndRE5#*%+;V9dGBt z7ap!D^KQs4#-cfy&&Gob-nT;Wmmgp34DplCIzG*ZKPjFdz)2#|&z`gWKt@7BKnMr{ zAs_^VfDjM@LO=)z0U;m+{x1Tb4)+pxPcx0b@3&!2M|b|1a?GDgOs3R%H~DrNPWNfO z2`kv8eMLK5+k^*jzfhU?Xxk-bwq90wL#wXVOYFBwX{R$oe*;X{yHB1!drF^>?yT2+ zqf<3C>LS{hLb8Gx8)>hULfb{_Lq?5nN`qQO8`pQk=% z&ai6$z5F5ti{tsi)+)2Uhv|=#v2|KRwz<(Kd-4xOEM%80U|&IhyW2F0z`la z5CI}U1c(3;_+JEW?k*KL$7jmd_iad*+AF`FGS7>NY7Msxu0We_1eA{EcjfDR1x)27 zQ`Os9wt`0$Co+Zu?1!`Ll&b)hPaM=LxKmK|$J_h6JFpIGffYs(v&{k1y>Q?d@npb~ z&>pa~IhGyRx(myoj(k70u7M^P#8EtSnQciLXiygnl8J6$DJE%9hlXIFN4o8@VI*nL zfTmy&d4cINHKTtGX@qw^{z{|r$dw1KJaOeCjjF}RM`?sDIL=DkzpkGC0H*!AegFUf literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat new file mode 100644 index 0000000000000000000000000000000000000000..6b0fc39e3e659899eea177e1993df7fcc14a6083 GIT binary patch literal 8192 zcmeI1zfQwI490z_)TaMio&lAq;?i8wL}FuO044^uOmz;T)?DxtSmwv?}q{iS#Lsmr-=4FCeKEG*JGX<3SXxrX`AGS__a0!)AjFaajO1egF5U;<2l z2`~XBuw4Wmo^AwO;X4)Q`z~Zh?VUewS@hQ%^#+a%Zoys+0xGlBQ^h%7z`j`I)!Os2 zn~ff_S->%zFFSLp;85ZXlZFK&*maeowG3xt>4fokI!Q1~V}C5Om?}T=od9Ye8eo&( z*GefFrY64)P4WlI*HT8(N zfC(^x?IQ5_d?Vlr->F*P_dzeUcmKR)RbMSMTexL#2ljF!VC`smSGCR;a3JQT+IU@5 z_11%h4{`$Mi^>eodSdGxQ_F%e?8SbPrczBD=|+hYcvclfMle^1G?4LOD%M{tk4>pGNT{lwoG_ccDjq=aq3P25}@J%KlH^aKu0ZZ4idH*cWNmXd;K zoXuatqkXUN!nc7eM8xR%8j+2ujbZThFsJiJF>2|L%aK-QdgdZ+zsYEGU4I>o?RSG) z$K4e?%O<*4y_jCm#OV^ z%iiAA*XxBe(_aQ_$;%%BjkEGD|DA87Z!RtypNndu*I3(+?J+5;2b&d1?k+(@009IL bKmY**5I_I{1Q0*~fgc5iGIcwTt^MfxGuieXjZk45o7=7~Aa(&|ZxC{9>rt@dfYT=K|v1aD_WFqab$!Kw1e{GHBkAr*1 zpNih)0^OSqrWY0Q`zpPwnXM}^76>4K00IagfB*srAbheKZoe|J&@T%=*ey3p z-@Y~E>xm@QD}#+>K-rbX_gV}2!JFWS)%KmY** a5I_I{1Q0*~0R#|0;1_|R%>4F)Jhm^H*DqcG literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat new file mode 100644 index 0000000000000000000000000000000000000000..08acdcee31e218c5d9c3b4f62ef38fb0f42c8e72 GIT binary patch literal 8192 zcmeI0F%H5o3`LzHwH@IGY>Y55aR$W95tsqN#?p}!a05=kDL6wJ7&rkqNmHezAhDun zDX#M!*UH;s*@}qKWi4?&bv||>A8Q&vD{ILgw+qdzb>$-caL8zL-G8;t_UGws=&PcC zIbl@l$4sIo{#?Vmp827nv4H>tAOHafKmY;|fB*y_009X6BZ1>-Z)Br43lHqXMcLb3 zL%y9zGaVTelGlTP&Zw>m?|dU;bM2TM$;ub(?#18*9@Q?- literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c400.dat b/java/lance-namespace-hive3/metastore_db/seg0/c400.dat new file mode 100644 index 0000000000000000000000000000000000000000..1e8976f89fb63a0868c737d9434d15ecfdedc47c GIT binary patch literal 8192 zcmeI#F%E(-6oBDZLa-qY-h#=*19*nUK?mdR3Dm^R)xi^ZCmCL&Ffo_&2!d+4ca%$v)#Ylsj)009ILKmY**5I_I{1Q0;r2Le+WS6z;m_3Z_e Cb`~Q5 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c41.dat b/java/lance-namespace-hive3/metastore_db/seg0/c41.dat new file mode 100644 index 0000000000000000000000000000000000000000..81ddeed84ad99ee31dbbf74e2885d43ad152acaf GIT binary patch literal 16384 zcmeHOOKcle6g@Loy*AFpRG_e;C{e-j7g$iqDa_woO5qtdd!(ry2PRYluecT9iB!AqAP z704qiEqrOMQfhj9`yNG1U=aB(ib`$KJ5yw20CpbnP?Bj5$p8|eBr^;W;UX#ILlGHS zPI<*Eukr;+A|)_@T!(?Jhe#kTFoXf(sIRSijcW5Ont1b< zuTBoP>0??`@RiBn_D~X*Dp}m2uULy4)#_%koxna_D9*?fmJ-hyrE6y{7O*$otyvJQje+ zpYSAppzv85jZB~-AGZHN;oAyVv8*1ymyf!Ok3o1r;b9uJf24KoD+*i05WR#YiDg1N zquO6$QQpYEuJCo*u2rVb<8OtZD%_!UrT?GzYxw?;LuYpR|KpgHBh&t97v9YO2OqUV zl7RmH|3A5fuYZ_#KMBD96_}zNz&Ck4M4Vr7B28I91}XWIc0Ug#*y&CTpw?%XVy7qu z@S_z<5~?M>$B0r2;72Q(f;|r_Lm@y22}e#VOEG|-M>Jc~byvN8I7*SH9AE@Pa;J2$ zuuBqIiUPuUI8_Oi1azvZG+UK2doMX@3IRH^30T-wIVnm2{Moch3v1GsQtHDs4KA5~ ze>Pn#{Mls5{fF~#G$2D=s~NuEDARx}5@8Yf1+Ka7P_j}s^JAI8GkzX|gHeg^Sa#e1ABiHKud zUvGT^wjLse!vbR%k=Lh2eWO*W1?M1}DU!rp{h2uGMpC%DKNCmcNE#FROx#r+_X?B2 zJzD5Sozfz{JXstGpaiGbd*q0F$1DQVgzbHqNAZ?f^2}q4os05pr?nk9Y;l)hi%nywi4g??o0SG_<0uX=z1Rwwb2teQ;37m?(k*&Tge6SN|Wp8f{ z`F0}BbYyUpydDH}TJ@>$&o?qQrH}RoRo0Fk>?~j|t14qR+c>#e3xNOxAOHafKmY;| XfB*y_009U<;3onzS^N6pvV6P%AQ>&m literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c421.dat b/java/lance-namespace-hive3/metastore_db/seg0/c421.dat new file mode 100644 index 0000000000000000000000000000000000000000..65775ee7bfbd1fe9a4e81f326933d49be9138b53 GIT binary patch literal 8192 zcmeI$Ee^sk6u|MxGuieXjZk3gY7=3JuT%Wi;?0i0q>HJx=TKMB~qM3z0nMm7jGFn{MUt44O4K00IagfB*srAbheK?yxqp)GzZt*pZv1 zZ{Oc{L6;HW?BpOap`f8a zza_u!EMNR}k*$b0?V)9HEaKQ5EZ>dk`rfuA{Bb+i%(}@A?a)Ard)s_7*M7N5?rJ}? zx@p`^M4m-@?u|A5z9&Nn0R#|0009ILKmY**5I_Kd{}MPHcTP6?Ci}n7;;MXmrR9@E zUg-IeyS~D?{&hs>8?kdI?JewM8f{y3d$X02B)(hZA@7T5XL)>{5De)RoQ z(Yst=aMzm|MMeC&TJLJ+`&x_%0tg_000IagfB*srAbfaii?* zUqil`NHaY$I7nU{1hkH-r@}tp$k5z;w6iF)_UOTupUJY!=my?>PIC1DdIS(a009IL YKmY**5I_I{1Q7T^U?MBOx_2t3FYvf6QUCw| literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c461.dat b/java/lance-namespace-hive3/metastore_db/seg0/c461.dat new file mode 100644 index 0000000000000000000000000000000000000000..e6d98541fb79659dd82e6c495be7eda4795dd219 GIT binary patch literal 8192 zcmeI$u?@m75J1s$h#Z%UKu3#&M8ynr~rwMhLQ=`fQo6D0XjB-!;T{-1VoL# zB|G+=lT%)2%SJ?u_E*dNX#JQDF`veC{wP}`{Bb$e%u2fx>Bdb)i|hJpYb}2o-Fo4z z49z7(^F^7>_1V$#Gnr_gmsvf;Yg8n^hX5l22q1s} a0tg_000IagfB*sr{3tM%W!UMgJwE}e#Vuq2 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c470.dat b/java/lance-namespace-hive3/metastore_db/seg0/c470.dat new file mode 100644 index 0000000000000000000000000000000000000000..c9f2eb1cae75e19bcc6f3d1feb17572a3f80c36e GIT binary patch literal 8192 zcmeI#p$@_@5P;$9(u@iO9zjr8Bm%)BU=W0tKmZ92O@b%kvGx);9s!Qq%9b(&20{KV z>uz^VZ~fe4Cn8So=g4f%ZEjAn-ppxyuSSyo_&V3hrmXhjqOLX%@#UN6Ei6~bUe#xg zu9|makyn$JeXVCWv{XnTfB*srAbHJxYTKeO1q?Nf|xkx)~GJ3eKzmCS^4})9B zKNY>pCAwF=nSOML-&cw5%zRzRu|NO;1Q0*~0R#|0009ILK;Rz*cKel)g??H1!A{&P zd;8WUUorr~3;OQZJwY literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c51.dat b/java/lance-namespace-hive3/metastore_db/seg0/c51.dat new file mode 100644 index 0000000000000000000000000000000000000000..dfff21083bb55b7163ac47cd9d88d2a271c61eda GIT binary patch literal 8192 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 Lv(SfMKi>TVu>A~v literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c90.dat b/java/lance-namespace-hive3/metastore_db/seg0/c90.dat new file mode 100644 index 0000000000000000000000000000000000000000..25ed408e137a7afff470bc7ea34c04876fe58333 GIT binary patch literal 24576 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 QKr-;Z#=!mGp8E5@0eJNGApigX literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cb1.dat b/java/lance-namespace-hive3/metastore_db/seg0/cb1.dat new file mode 100644 index 0000000000000000000000000000000000000000..812444f3bf3fc51b41f0a02dcbe2667cd84debd5 GIT binary patch literal 8192 zcmeI$e`wTo9LMq3-Q4}y&)aU>?e_ckcGKmr(rTI?%U@;wSmnxDty-3vX6mN7(z0c% z)Y__PW)uY#;U6Lu6d@H+Q4kVBKdAl?8AV|cQ4$6AzSnCf!&cFs!S`T~d*1iE+xPZ@ z4eqcRfX}{?H$M%~(WK6gK4yJ-=S{YePpl`p)(%@j9F)%m3q7F!$jYwBS#O9 z+$TSJ@Y@SnjE<2b19qRhu>Wl%==UKFz92%15W$W`Pb zqKF_*k%xRmKB9^!3KRt>R1~5}QG}QxhGIoA;)*y*6eTECl%h;ghH^zYDijr{R8*o$ zQH5$nHEI+!s8!UWPEm(?MLil64QNy}qDj$&gd%}vMKi`T`~gf*1ks`h;T%O66BQYl zq{zf%MHZ$gvN2VWgL4(RI8PD5G({e!EAnx^B8m$X1-MXAh*m`rW+-BqsVK%pia2H| zO5mKT6mGVv4DMo8Iou_x3b;9{O1QbID!6&7YPk8T8n^|jTDVJ9b#Rxd>fsiu8sIKh zHNq`YHNh=rr3K)YsDf}yRUx=GRT%CHRR-LZs!X`6R9SG#RM~LtsvNkhRk?82s3LI7 zRe5k7s(iQ=swmvGssgy{RE2QYtBT+{RWZ05RK;*Ns^V}rschXYm92ZT%GO<}vUP7! z*}Au?Y~58VTX(g})?K5rb#GJIx@%Ro?mCsNd%MckU9Ylr?@-yg8&nCnjjCq2O{{UY zc(=+H?@`&}n^m^>7L_f2r^*)JsZ1Klcw)hh&TYN}mi|y#_>-)3TYSID7Jo{W`af>}m%W>} zfVY6RfVY6Rz<*pIFdi8|pqj>LHcd;K{u}*~4%08`C-eh)guX&wrq9wLx{L0hTj)C4 zMVHehbS`bBlW8L@r%`HeG=OoZ=`ZwqdYpbnKc?@}H|Qby0zE(nX+PaYH__F!lP;qR z>1;Zkw$NG{r@1seY1;4fC;AQjnjWJc(zobq^dNnX?xTBXAKgmV)0K1uZKLz)Ogfb& zXeBMAnbeome~O-@C+HXSD1DEx`ZN8G9;ctvqx5}xguY4-(&y=ZIzapBcG^SN(k|LT+voy1i%z30w2qe2 ld>W=mic|ClI!wQ!$LL4&9r`*wL|>#cuttBX?SsFb{1bo$+ZF%- literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cc0.dat b/java/lance-namespace-hive3/metastore_db/seg0/cc0.dat new file mode 100644 index 0000000000000000000000000000000000000000..226872006d7e7681f9732c7e2268f2312c42abd0 GIT binary patch literal 8192 zcmeI1y-or_5P;_d`8^c1va&H+ZL;?R90n5+qGABigF-C~aPS0bv@<4_))u~qrSS<& zd;v=n-$9){Zjr#!8#8-h*qynL-TN{P0G9xu;Y*AeKSumG8f1Mmhx6}XjHRb88(29X zRMYY%9XF53#gzA?Dt~fYD-QC*&kByY{(*Uo0}Kla-rqBJqo`1d43GgbKnBPF86X2> zfDDiUGC&5%!2dFE|9Gvz1wNDfexCvzSBn!*DeGf}a0JO^?QJCejPnrGp@kPjL$C&` zU2a$o=N{v{@32fKV=>cd=W!{9k?(nqgFgX8++(-0U4vN&6&nqR`7Cl`2-f4Q@8xpL z!uti=#;arGITr-75{yr5+F@qaHW<(Kx^h#??pr+Av{YL3pOymKmp?&Y+~H=qb@S= V>ckx5(_g!cb=gm8#4RL|*JS^htr_`8HUa5uVga3OcH{e2zUYA=4frH#)9JYPlzHwdPKfWqCh%J%sVHk_ACea_xGdeB)w ziqlMaG>Qx*bmO}+CGe7yB-}kf3677z#XL%)s2iYc6FTjIDrHoxvX}N%si5kj3|~s( z=`Msvy5C)_a3a_Md RtIj>O58!+O>G0`x?-%c{mUjRE literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cf0.dat b/java/lance-namespace-hive3/metastore_db/seg0/cf0.dat new file mode 100644 index 0000000000000000000000000000000000000000..fb40ee421916f7cc965275d19623aec219c8c959 GIT binary patch literal 8192 zcmeI#u?@m75J1s$gc27NtU#5P7Ks_6G!%$60Evzoi3wPT4OoJX41fg3B}SGB1q}uI zj&gDCEMNS($VNn*-p`R)%q_+t)Z?7a@7+k!A75*&tlH`*EE;NaA6~wBUj1U3?A3i{ zdC|O^h`gHg>}x&!uBSo@0R#|0009ILKmY**5I_Kd{}MPHw@%i2rtp8C*{pawWvC~G zL9Xk^?i{5XoflH+HMdwv9aWhkfB*srAbmQns!3)6?w%oG2D4 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/service.properties b/java/lance-namespace-hive3/metastore_db/service.properties new file mode 100644 index 0000000..2647898 --- /dev/null +++ b/java/lance-namespace-hive3/metastore_db/service.properties @@ -0,0 +1,23 @@ +#/Users/zhaoqinye/oss/lance-namespace-impls/java/lance-namespace-hive3/metastore_db +# ******************************************************************** +# *** Please do NOT edit this file. *** +# *** CHANGING THE CONTENT OF THIS FILE MAY CAUSE DATA CORRUPTION. *** +# ******************************************************************** +#Tue Dec 30 21:25:14 PST 2025 +SysconglomeratesIdentifier=32 +SyscolumnsIdentifier=144 +derby.serviceLocale=en_US +SystablesIdentifier=96 +SysconglomeratesIndex3Identifier=81 +derby.storage.propertiesId=16 +derby.serviceProtocol=org.apache.derby.database.Database +SyscolumnsIndex1Identifier=161 +SysschemasIndex2Identifier=225 +SystablesIndex2Identifier=129 +SyscolumnsIndex2Identifier=177 +SysconglomeratesIndex2Identifier=65 +SysschemasIndex1Identifier=209 +SysschemasIdentifier=192 +SystablesIndex1Identifier=113 +SysconglomeratesIndex1Identifier=49 +#--- last line, don't put anything after this line --- diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java index dcc4dfc..e53fe6d 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java @@ -27,6 +27,8 @@ import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; @@ -220,11 +222,12 @@ public void namespaceExists(NamespaceExistsRequest request) { public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ObjectIdentifier id = ObjectIdentifier.of(request.getId()); String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; + String behavior = request.getBehavior() != null ? request.getBehavior() : "Restrict"; ValidationUtil.checkArgument( !id.isRoot() && id.levels() <= 2, "Expect a 2-level namespace but get %s", id); - Map properties = doDropNamespace(id, mode); + Map properties = doDropNamespace(id, mode, behavior); DropNamespaceResponse response = new DropNamespaceResponse(); response.setProperties(properties); @@ -317,7 +320,20 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request return response; } - // Removed: dropTable(DropTableRequest) - using default implementation from interface + @Override + public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); + + ValidationUtil.checkArgument( + tableId.levels() == 3, "Expect 3-level table identifier but get %s", tableId); + + String location = doDropTable(tableId); + + DeregisterTableResponse response = new DeregisterTableResponse(); + response.setId(request.getId()); + response.setLocation(location); + return response; + } public void setConf(Configuration conf) { this.hadoopConf = conf; @@ -590,16 +606,16 @@ protected String doDropTable(ObjectIdentifier id) { } } - protected Map doDropNamespace(ObjectIdentifier id, String mode) { + protected Map doDropNamespace(ObjectIdentifier id, String mode, String behavior) { try { if (id.levels() == 1) { // Drop catalog - return doDropCatalog(id.levelAtListPos(0).toLowerCase(), mode); + return doDropCatalog(id.levelAtListPos(0).toLowerCase(), mode, behavior); } else { // Drop database return doDropDatabase( - id.levelAtListPos(0).toLowerCase(), id.levelAtListPos(1).toLowerCase(), mode); + id.levelAtListPos(0).toLowerCase(), id.levelAtListPos(1).toLowerCase(), mode, behavior); } } catch (TException | InterruptedException e) { if (e instanceof InterruptedException) { @@ -610,7 +626,7 @@ protected Map doDropNamespace(ObjectIdentifier id, String mode) } } - private Map doDropCatalog(String catalog, String mode) + private Map doDropCatalog(String catalog, String mode, String behavior) throws TException, InterruptedException { Catalog catalogObj = Hive3Util.getCatalogOrNull(clientPool, catalog); if (catalogObj == null) { @@ -621,13 +637,16 @@ private Map doDropCatalog(String catalog, String mode) } } - // Check for child databases (RESTRICT mode only) - List databases = clientPool.run(client -> client.getAllDatabases(catalog)); - if (!databases.isEmpty()) { - throw new InvalidInputException( - String.format( - "Catalog %s is not empty. Contains %d databases: %s", - catalog, databases.size(), databases)); + // Check for child databases (RESTRICT behavior only, not for Cascade) + boolean cascade = "Cascade".equalsIgnoreCase(behavior); + if (!cascade) { + List databases = clientPool.run(client -> client.getAllDatabases(catalog)); + if (!databases.isEmpty()) { + throw new InvalidInputException( + String.format( + "Catalog %s is not empty. Contains %d databases: %s", + catalog, databases.size(), databases)); + } } // Collect catalog properties @@ -650,7 +669,8 @@ private Map doDropCatalog(String catalog, String mode) return properties; } - private Map doDropDatabase(String catalog, String db, String mode) + private Map doDropDatabase( + String catalog, String db, String mode, String behavior) throws TException, InterruptedException { Database database = Hive3Util.getDatabaseOrNull(clientPool, catalog, db); if (database == null) { @@ -662,13 +682,16 @@ private Map doDropDatabase(String catalog, String db, String mod } } - // Check if database contains tables (RESTRICT mode only) - List tables = doListTables(catalog, db); - if (!tables.isEmpty()) { - throw new InvalidInputException( - String.format( - "Database %s.%s is not empty. Contains %d tables: %s", - catalog, db, tables.size(), tables)); + // Check if database contains tables (RESTRICT behavior only, not for Cascade) + boolean cascade = "Cascade".equalsIgnoreCase(behavior); + if (!cascade) { + List tables = doListTables(catalog, db); + if (!tables.isEmpty()) { + throw new InvalidInputException( + String.format( + "Database %s.%s is not empty. Contains %d tables: %s", + catalog, db, tables.size(), tables)); + } } // Collect database properties @@ -690,9 +713,10 @@ private Map doDropDatabase(String catalog, String db, String mod } // Drop the database + final boolean cascadeDrop = cascade; clientPool.run( client -> { - client.dropDatabase(catalog, db, false, true, false); + client.dropDatabase(catalog, db, false, true, cascadeDrop); return null; }); diff --git a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java index 0d04c2d..50ab8b2 100644 --- a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java +++ b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java @@ -18,12 +18,12 @@ import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; -import org.lance.namespace.model.DropTableRequest; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -31,6 +31,8 @@ import org.apache.arrow.memory.BufferAllocator; import org.apache.arrow.memory.RootAllocator; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hive.conf.HiveConf; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; @@ -96,8 +98,12 @@ public void setUp() throws Exception { testCatalog = "hive"; // Default catalog in Hive 3.x testDatabase = "test_db_" + uniqueId; + // Set up Hadoop configuration with metastore URI + Configuration hadoopConf = new Configuration(); + hadoopConf.set(HiveConf.ConfVars.METASTOREURIS.varname, METASTORE_URI); + namespace.setConf(hadoopConf); + Map config = new HashMap<>(); - config.put("hive.metastore.uris", METASTORE_URI); config.put("client.pool-size", "3"); config.put("root", "/tmp/lance-integration-test"); @@ -203,10 +209,10 @@ public void testTableOperations() { ListTablesResponse listResponse = namespace.listTables(listRequest); assertThat(listResponse.getTables()).contains(tableName); - // Drop table - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(Arrays.asList(testCatalog, testDatabase, tableName)); - namespace.dropTable(dropRequest); + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(testCatalog, testDatabase, tableName)); + namespace.deregisterTable(deregisterRequest); // Verify table doesn't exist assertThatThrownBy(() -> namespace.describeTable(describeRequest)) diff --git a/python/Makefile b/python/Makefile index 974c606..e2255be 100644 --- a/python/Makefile +++ b/python/Makefile @@ -28,21 +28,21 @@ test-glue: uv run pytest tests/test_glue.py # ============================================================================ -# Hive +# Hive2 # ============================================================================ .PHONY: lint-hive lint-hive: - uv run ruff check src/lance_namespace_impls/hive.py tests/test_hive.py - uv run ruff format --check src/lance_namespace_impls/hive.py tests/test_hive.py + uv run ruff check src/lance_namespace_impls/hive2.py src/lance_namespace_impls/hive3.py tests/test_hive2.py tests/test_hive3.py tests/test_hive2_integration.py tests/test_hive3_integration.py + uv run ruff format --check src/lance_namespace_impls/hive2.py src/lance_namespace_impls/hive3.py tests/test_hive2.py tests/test_hive3.py tests/test_hive2_integration.py tests/test_hive3_integration.py .PHONY: install-hive install-hive: - uv sync --extra hive2 --extra dev + uv sync --extra hive2 --extra hive3 --extra dev .PHONY: test-hive test-hive: - uv run pytest tests/test_hive.py + uv run pytest tests/test_hive2.py tests/test_hive3.py # ============================================================================ # Unity @@ -72,7 +72,7 @@ lint-iceberg: .PHONY: install-iceberg install-iceberg: - uv sync --extra dev + uv sync --extra iceberg --extra dev .PHONY: test-iceberg test-iceberg: @@ -139,7 +139,15 @@ integ-test: .PHONY: integ-test-hive integ-test-hive: - uv run pytest tests/test_hive.py -m integration + uv run pytest tests/test_hive2_integration.py tests/test_hive3_integration.py -v + +.PHONY: integ-test-hive2 +integ-test-hive2: + uv run pytest tests/test_hive2_integration.py -v + +.PHONY: integ-test-hive3 +integ-test-hive3: + uv run pytest tests/test_hive3_integration.py -v .PHONY: integ-test-polaris integ-test-polaris: diff --git a/python/pyproject.toml b/python/pyproject.toml index 34f8b4f..8ce7cb2 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -30,8 +30,9 @@ hive3 = [ "thrift>=0.13.0", "hive-metastore-client>=1.0.0", ] -unity = [] +iceberg = [] polaris = [] +unity = [] all = [ "boto3>=1.35.0", "botocore>=1.35.0", @@ -41,6 +42,7 @@ all = [ dev = [ "pytest>=7.0.0", "pytest-cov>=4.0.0", + "ruff>=0.4.0", ] [tool.pytest.ini_options] diff --git a/python/src/lance_namespace_impls/glue.py b/python/src/lance_namespace_impls/glue.py index e12e70f..a2bd3c3 100644 --- a/python/src/lance_namespace_impls/glue.py +++ b/python/src/lance_namespace_impls/glue.py @@ -1,13 +1,13 @@ """ Lance Glue Namespace implementation using AWS Glue Data Catalog. """ -from typing import Dict, List, Optional, Any, Union -from urllib.parse import urlparse -import os + +from typing import Dict, List, Optional, Any try: import boto3 from botocore.config import Config + HAS_BOTO3 = True except ImportError: boto3 = None @@ -18,10 +18,6 @@ import pyarrow as pa from lance.namespace import LanceNamespace -from lance_namespace_impls.schema import ( - convert_json_arrow_schema_to_pyarrow, - convert_json_arrow_type_to_pyarrow, -) from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, ListNamespacesResponse, @@ -47,9 +43,6 @@ DeregisterTableRequest, DeregisterTableResponse, TableExistsRequest, - JsonArrowSchema, - JsonArrowField, - JsonArrowDataType, ) @@ -61,59 +54,59 @@ class GlueNamespace(LanceNamespace): """Lance Glue Namespace implementation using AWS Glue Data Catalog. - + This namespace implementation integrates Lance with AWS Glue Data Catalog, allowing you to manage Lance table metadata in a centralized AWS service. - + Usage Examples: - + >>> from lance_namespace import connect - + >>> # Connect using default AWS credentials >>> namespace = connect("glue", { ... "region": "us-east-1" ... }) - + >>> # Connect with specific credentials >>> namespace = connect("glue", { ... "region": "us-east-1", ... "access_key_id": "YOUR_ACCESS_KEY", ... "secret_access_key": "YOUR_SECRET_KEY" ... }) - + >>> # Connect with custom catalog ID and endpoint >>> namespace = connect("glue", { ... "region": "us-east-1", ... "catalog_id": "123456789012", ... "endpoint": "https://glue.example.com" ... }) - + >>> # Create a database (namespace) >>> from lance_namespace_urllib3_client.models import CreateNamespaceRequest >>> namespace.create_namespace(CreateNamespaceRequest( ... id=["my_database"], ... properties={"description": "My Lance tables"} ... )) - + >>> # List databases >>> from lance_namespace_urllib3_client.models import ListNamespacesRequest >>> response = namespace.list_namespaces(ListNamespacesRequest()) >>> print(response.namespaces) - + >>> # Create a table >>> from lance_namespace_urllib3_client.models import CreateTableRequest >>> namespace.create_table(CreateTableRequest( ... id=["my_database", "my_table"], ... var_schema=arrow_schema # PyArrow schema ... ), data_bytes) - + Note: Requires boto3 to be installed: pip install lance-namespace[glue] """ - + def __init__(self, **properties): """Initialize the Glue namespace. - + Args: catalog_id: Glue catalog ID (AWS account ID) endpoint: Optional custom Glue endpoint @@ -133,7 +126,7 @@ def __init__(self, **properties): "boto3 is required for GlueNamespace. " "Install with: pip install lance-namespace[glue]" ) - + self.config = GlueNamespaceConfig(properties) self._glue = None # Lazy initialization to support pickling @@ -149,7 +142,7 @@ def glue(self): if self._glue is None: self._glue = self._initialize_glue_client() return self._glue - + def _initialize_glue_client(self): """Initialize the AWS Glue client.""" session = boto3.Session( @@ -159,247 +152,254 @@ def _initialize_glue_client(self): aws_secret_access_key=self.config.secret_access_key, aws_session_token=self.config.session_token, ) - + config_kwargs = {} if self.config.max_retries: - config_kwargs['retries'] = { - 'max_attempts': self.config.max_retries, - 'mode': self.config.retry_mode or 'standard' + config_kwargs["retries"] = { + "max_attempts": self.config.max_retries, + "mode": self.config.retry_mode or "standard", } - + glue_client = session.client( - 'glue', + "glue", endpoint_url=self.config.endpoint, - config=Config(**config_kwargs) if config_kwargs else None + config=Config(**config_kwargs) if config_kwargs else None, ) - + # Register catalog ID if provided if self.config.catalog_id: self._register_catalog_id(glue_client, self.config.catalog_id) - + return glue_client - + def _register_catalog_id(self, glue_client, catalog_id): """Register the Glue Catalog ID with the client.""" event_system = glue_client.meta.events - + def add_catalog_id(params, **kwargs): - if 'CatalogId' not in params: - params['CatalogId'] = catalog_id - - event_system.register('provide-client-params.glue', add_catalog_id) - + if "CatalogId" not in params: + params["CatalogId"] = catalog_id + + event_system.register("provide-client-params.glue", add_catalog_id) + def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: """List namespaces (databases) in Glue.""" # Only list databases if we're at root namespace (no id or empty id) if request.id and len(request.id) > 0: # Hierarchical namespaces are not supported in Glue return ListNamespacesResponse(namespaces=[]) - + try: databases = [] next_token = None - + while True: if next_token: response = self.glue.get_databases(NextToken=next_token) else: response = self.glue.get_databases() - - for db in response.get('DatabaseList', []): - databases.append(db['Name']) - - next_token = response.get('NextToken') + + for db in response.get("DatabaseList", []): + databases.append(db["Name"]) + + next_token = response.get("NextToken") if not next_token: break - + return ListNamespacesResponse(namespaces=databases) except Exception as e: raise RuntimeError(f"Failed to list namespaces: {e}") - - def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: """Describe a namespace (database) in Glue.""" # Handle root namespace if not request.id or len(request.id) == 0: # Root namespace always exists properties = {} if self.config.root: - properties['location'] = self.config.root - properties['description'] = 'Root Glue catalog namespace' + properties["location"] = self.config.root + properties["description"] = "Root Glue catalog namespace" return DescribeNamespaceResponse(properties=properties) - + if len(request.id) != 1: raise ValueError("Glue namespace requires exactly one level identifier") - + database_name = request.id[0] - + try: response = self.glue.get_database(Name=database_name) - database = response['Database'] - - properties = database.get('Parameters', {}) - if 'LocationUri' in database: - properties['location'] = database['LocationUri'] - if 'Description' in database: - properties['description'] = database['Description'] - + database = response["Database"] + + properties = database.get("Parameters", {}) + if "LocationUri" in database: + properties["location"] = database["LocationUri"] + if "Description" in database: + properties["description"] = database["Description"] + return DescribeNamespaceResponse(properties=properties) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": raise RuntimeError(f"Namespace does not exist: {database_name}") raise RuntimeError(f"Failed to describe namespace: {e}") - - def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: """Create a namespace (database) in Glue.""" # Handle root namespace if not request.id or len(request.id) == 0: raise RuntimeError("Root namespace already exists") - + if len(request.id) != 1: raise ValueError("Glue namespace requires exactly one level identifier") - + database_name = request.id[0] - database_input = {'Name': database_name} - + database_input = {"Name": database_name} + if request.properties: parameters = {} for key, value in request.properties.items(): - if key == 'description': - database_input['Description'] = value - elif key == 'location': - database_input['LocationUri'] = value + if key == "description": + database_input["Description"] = value + elif key == "location": + database_input["LocationUri"] = value else: parameters[key] = value if parameters: - database_input['Parameters'] = parameters - + database_input["Parameters"] = parameters + try: self.glue.create_database(DatabaseInput=database_input) return CreateNamespaceResponse() except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'AlreadyExistsException': + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "AlreadyExistsException": raise RuntimeError(f"Namespace already exists: {database_name}") raise RuntimeError(f"Failed to create namespace: {e}") - + def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace (database) in Glue.""" # Handle root namespace if not request.id or len(request.id) == 0: raise RuntimeError("Cannot drop root namespace") - + if len(request.id) != 1: raise ValueError("Glue namespace requires exactly one level identifier") - + database_name = request.id[0] - + try: # Check if database is empty tables_response = self.glue.get_tables(DatabaseName=database_name) - if tables_response.get('TableList'): + if tables_response.get("TableList"): raise RuntimeError(f"Cannot drop non-empty namespace: {database_name}") - + self.glue.delete_database(Name=database_name) return DropNamespaceResponse() except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": raise RuntimeError(f"Namespace does not exist: {database_name}") if isinstance(e, RuntimeError): raise raise RuntimeError(f"Failed to drop namespace: {e}") - + def namespace_exists(self, request: NamespaceExistsRequest) -> None: """Check if a namespace exists.""" # Handle root namespace - it always exists if not request.id or len(request.id) == 0: return # Root namespace always exists - + if len(request.id) != 1: raise ValueError("Glue namespace requires exactly one level identifier") - + database_name = request.id[0] - + try: self.glue.get_database(Name=database_name) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": raise RuntimeError(f"Namespace does not exist: {database_name}") raise RuntimeError(f"Failed to check namespace existence: {e}") - + def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a namespace.""" # Handle root namespace - no tables at root level if not request.id or len(request.id) == 0: return ListTablesResponse(tables=[]) - + if len(request.id) != 1: raise ValueError("Glue namespace requires exactly one level identifier") - + database_name = request.id[0] - + try: tables = [] next_token = None - + while True: if next_token: response = self.glue.get_tables( - DatabaseName=database_name, - NextToken=next_token + DatabaseName=database_name, NextToken=next_token ) else: response = self.glue.get_tables(DatabaseName=database_name) - - for table in response.get('TableList', []): + + for table in response.get("TableList", []): # Only include Lance tables if self._is_lance_table(table): - tables.append(table['Name']) - - next_token = response.get('NextToken') + tables.append(table["Name"]) + + next_token = response.get("NextToken") if not next_token: break - + return ListTablesResponse(tables=tables) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": raise RuntimeError(f"Namespace does not exist: {database_name}") raise RuntimeError(f"Failed to list tables: {e}") - + def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table.""" database_name, table_name = self._parse_table_identifier(request.id) - + try: - response = self.glue.get_table( - DatabaseName=database_name, - Name=table_name - ) - table = response['Table'] - + response = self.glue.get_table(DatabaseName=database_name, Name=table_name) + table = response["Table"] + if not self._is_lance_table(table): - raise RuntimeError(f"Table is not a Lance table: {database_name}.{table_name}") - - location = table.get('StorageDescriptor', {}).get('Location') + raise RuntimeError( + f"Table is not a Lance table: {database_name}.{table_name}" + ) + + location = table.get("StorageDescriptor", {}).get("Location") if not location: - raise RuntimeError(f"Table has no location: {database_name}.{table_name}") + raise RuntimeError( + f"Table has no location: {database_name}.{table_name}" + ) return DescribeTableResponse( - location=location, - storage_options=self.config.storage_options + location=location, storage_options=self.config.storage_options ) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': - raise RuntimeError(f"Table does not exist: {database_name}.{table_name}") + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": + raise RuntimeError( + f"Table does not exist: {database_name}.{table_name}" + ) if isinstance(e, RuntimeError): raise raise RuntimeError(f"Failed to describe table: {e}") - - def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: + + def create_table( + self, request: CreateTableRequest, request_data: bytes + ) -> CreateTableResponse: """Create a table with data from Arrow IPC stream. This operation is not supported. Use create_empty_table to declare table metadata, @@ -409,67 +409,70 @@ def create_table(self, request: CreateTableRequest, request_data: bytes) -> Crea "create_table is not supported. Use create_empty_table to declare table metadata, " "then use Lance SDK to create the actual table data." ) - - def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: """Create an empty table (metadata only) in Glue catalog.""" database_name, table_name = self._parse_table_identifier(request.id) - + # Determine table location - table_location = getattr(request, 'location', None) + table_location = getattr(request, "location", None) if not table_location: # Use default location pattern db_response = self.glue.get_database(Name=database_name) - db_location = db_response['Database'].get('LocationUri', '') + db_location = db_response["Database"].get("LocationUri", "") if db_location: table_location = f"{db_location}/{table_name}.lance" else: # Use S3 default location - table_location = f"s3://lance-namespace/{database_name}/{table_name}.lance" - + table_location = ( + f"s3://lance-namespace/{database_name}/{table_name}.lance" + ) + # Create a minimal schema for Glue (placeholder schema) glue_columns = [ { - 'Name': '__placeholder_id', - 'Type': 'bigint', - 'Comment': 'Placeholder column for empty table' + "Name": "__placeholder_id", + "Type": "bigint", + "Comment": "Placeholder column for empty table", } ] - + # Create Glue table entry without creating actual Lance dataset table_input = { - 'Name': table_name, - 'TableType': EXTERNAL_TABLE, - 'Parameters': { + "Name": table_name, + "TableType": EXTERNAL_TABLE, + "Parameters": { TABLE_TYPE: LANCE_TABLE_TYPE, - 'empty_table': 'true', # Mark as empty table + "empty_table": "true", # Mark as empty table + }, + "StorageDescriptor": { + "Location": table_location, + "Columns": glue_columns, + "InputFormat": "org.apache.hadoop.mapred.TextInputFormat", + "OutputFormat": "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", + "SerdeInfo": { + "SerializationLibrary": "org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe" + }, }, - 'StorageDescriptor': { - 'Location': table_location, - 'Columns': glue_columns, - 'InputFormat': 'org.apache.hadoop.mapred.TextInputFormat', - 'OutputFormat': 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat', - 'SerdeInfo': { - 'SerializationLibrary': 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' - } - } } - + # Add additional properties if specified if request.properties: - table_input['Parameters'].update(request.properties) - + table_input["Parameters"].update(request.properties) + try: - self.glue.create_table( - DatabaseName=database_name, - TableInput=table_input - ) + self.glue.create_table(DatabaseName=database_name, TableInput=table_input) except Exception as e: - if 'AlreadyExistsException' in str(e): - raise RuntimeError(f"Table already exists: {database_name}.{table_name}") + if "AlreadyExistsException" in str(e): + raise RuntimeError( + f"Table already exists: {database_name}.{table_name}" + ) raise RuntimeError(f"Failed to create empty table: {e}") - + return CreateEmptyTableResponse(location=table_location) - + def drop_table(self, request: DropTableRequest) -> DropTableResponse: """Drop a table - deletes both the Lance dataset and Glue catalog entry. @@ -480,163 +483,176 @@ def drop_table(self, request: DropTableRequest) -> DropTableResponse: "drop_table is not supported. Use deregister_table to remove table metadata, " "then use Lance SDK to delete the actual table data if needed." ) - + def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: """Register an existing Lance table in Glue.""" database_name, table_name = self._parse_table_identifier(request.id) - + if not request.location: raise ValueError("Location is required to register a table") - + # Read Lance dataset to get schema try: - dataset = lance.dataset(request.location, storage_options=self.config.storage_options) + dataset = lance.dataset( + request.location, storage_options=self.config.storage_options + ) schema = dataset.schema except Exception as e: - raise RuntimeError(f"Failed to read Lance dataset at {request.location}: {e}") - + raise RuntimeError( + f"Failed to read Lance dataset at {request.location}: {e}" + ) + # Create Glue table entry table_input = { - 'Name': table_name, - 'TableType': EXTERNAL_TABLE, - 'Parameters': { + "Name": table_name, + "TableType": EXTERNAL_TABLE, + "Parameters": { TABLE_TYPE: LANCE_TABLE_TYPE, }, - 'StorageDescriptor': { - 'Location': request.location, - 'Columns': self._convert_pyarrow_schema_to_glue_columns(schema) - } + "StorageDescriptor": { + "Location": request.location, + "Columns": self._convert_pyarrow_schema_to_glue_columns(schema), + }, } - + try: - self.glue.create_table( - DatabaseName=database_name, - TableInput=table_input - ) + self.glue.create_table(DatabaseName=database_name, TableInput=table_input) return RegisterTableResponse(location=request.location) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'AlreadyExistsException': - raise RuntimeError(f"Table already exists: {database_name}.{table_name}") + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "AlreadyExistsException": + raise RuntimeError( + f"Table already exists: {database_name}.{table_name}" + ) raise RuntimeError(f"Failed to register table: {e}") - - def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableResponse: + + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: """Deregister a table - removes only the Glue catalog entry, keeps the Lance dataset.""" database_name, table_name = self._parse_table_identifier(request.id) - + try: # Only remove from Glue catalog, don't delete the Lance dataset - self.glue.delete_table( - DatabaseName=database_name, - Name=table_name - ) + self.glue.delete_table(DatabaseName=database_name, Name=table_name) return DeregisterTableResponse() except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': - raise RuntimeError(f"Table does not exist: {database_name}.{table_name}") + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": + raise RuntimeError( + f"Table does not exist: {database_name}.{table_name}" + ) raise RuntimeError(f"Failed to deregister table: {e}") - + def table_exists(self, request: TableExistsRequest) -> None: """Check if a table exists.""" database_name, table_name = self._parse_table_identifier(request.id) - + try: - response = self.glue.get_table( - DatabaseName=database_name, - Name=table_name - ) - if not self._is_lance_table(response['Table']): - raise RuntimeError(f"Table is not a Lance table: {database_name}.{table_name}") + response = self.glue.get_table(DatabaseName=database_name, Name=table_name) + if not self._is_lance_table(response["Table"]): + raise RuntimeError( + f"Table is not a Lance table: {database_name}.{table_name}" + ) except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, '__class__') else '' - if error_name == 'EntityNotFoundException': - raise RuntimeError(f"Table does not exist: {database_name}.{table_name}") + error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" + if error_name == "EntityNotFoundException": + raise RuntimeError( + f"Table does not exist: {database_name}.{table_name}" + ) if isinstance(e, RuntimeError): raise raise RuntimeError(f"Failed to check table existence: {e}") - + def _parse_table_identifier(self, identifier: List[str]) -> tuple[str, str]: """Parse table identifier into database and table name.""" if not identifier or len(identifier) != 2: - raise ValueError("Table identifier must have exactly 2 parts: [database, table]") + raise ValueError( + "Table identifier must have exactly 2 parts: [database, table]" + ) return identifier[0], identifier[1] - + def _is_lance_table(self, glue_table: Dict[str, Any]) -> bool: """Check if a Glue table is a Lance table.""" - return glue_table.get('Parameters', {}).get(TABLE_TYPE, '').upper() == LANCE_TABLE_TYPE - - def _convert_pyarrow_schema_to_glue_columns(self, schema: pa.Schema) -> List[Dict[str, str]]: + return ( + glue_table.get("Parameters", {}).get(TABLE_TYPE, "").upper() + == LANCE_TABLE_TYPE + ) + + def _convert_pyarrow_schema_to_glue_columns( + self, schema: pa.Schema + ) -> List[Dict[str, str]]: """Convert PyArrow schema to Glue column definitions.""" columns = [] for field in schema: column = { - 'Name': field.name, - 'Type': self._convert_pyarrow_type_to_glue_type(field.type) + "Name": field.name, + "Type": self._convert_pyarrow_type_to_glue_type(field.type), } columns.append(column) return columns - + def _convert_pyarrow_type_to_glue_type(self, arrow_type: pa.DataType) -> str: """Convert PyArrow type to Glue/Hive type string.""" if pa.types.is_boolean(arrow_type): - return 'boolean' + return "boolean" elif pa.types.is_int8(arrow_type) or pa.types.is_uint8(arrow_type): - return 'tinyint' + return "tinyint" elif pa.types.is_int16(arrow_type) or pa.types.is_uint16(arrow_type): - return 'smallint' + return "smallint" elif pa.types.is_int32(arrow_type) or pa.types.is_uint32(arrow_type): - return 'int' + return "int" elif pa.types.is_int64(arrow_type) or pa.types.is_uint64(arrow_type): - return 'bigint' + return "bigint" elif pa.types.is_float32(arrow_type): - return 'float' + return "float" elif pa.types.is_float64(arrow_type): - return 'double' + return "double" elif pa.types.is_string(arrow_type): - return 'string' + return "string" elif pa.types.is_binary(arrow_type): - return 'binary' + return "binary" elif pa.types.is_date32(arrow_type) or pa.types.is_date64(arrow_type): - return 'date' + return "date" elif pa.types.is_timestamp(arrow_type): - return 'timestamp' + return "timestamp" elif pa.types.is_decimal(arrow_type): - return f'decimal({arrow_type.precision},{arrow_type.scale})' + return f"decimal({arrow_type.precision},{arrow_type.scale})" elif pa.types.is_list(arrow_type): - element_type = self._convert_pyarrow_type_to_glue_type(arrow_type.value_type) - return f'array<{element_type}>' + element_type = self._convert_pyarrow_type_to_glue_type( + arrow_type.value_type + ) + return f"array<{element_type}>" elif pa.types.is_struct(arrow_type): field_strs = [] for field in arrow_type: field_type = self._convert_pyarrow_type_to_glue_type(field.type) - field_strs.append(f'{field.name}:{field_type}') - return f'struct<{",".join(field_strs)}>' + field_strs.append(f"{field.name}:{field_type}") + return f"struct<{','.join(field_strs)}>" elif pa.types.is_map(arrow_type): key_type = self._convert_pyarrow_type_to_glue_type(arrow_type.key_type) value_type = self._convert_pyarrow_type_to_glue_type(arrow_type.item_type) - return f'map<{key_type},{value_type}>' + return f"map<{key_type},{value_type}>" else: # Default to string for unknown types - return 'string' - + return "string" + def __getstate__(self): """Prepare instance for pickling by excluding unpickleable objects.""" state = self.__dict__.copy() # Remove the unpickleable Glue client - state['_glue'] = None + state["_glue"] = None return state - + def __setstate__(self, state): """Restore instance from pickled state.""" self.__dict__.update(state) # The Glue client will be re-initialized lazily via the property - class GlueNamespaceConfig: """Configuration for GlueNamespace.""" - + # Glue configuration keys (without prefix as per documentation) CATALOG_ID = "catalog_id" ENDPOINT = "endpoint" @@ -648,22 +664,22 @@ class GlueNamespaceConfig: MAX_RETRIES = "max_retries" RETRY_MODE = "retry_mode" ROOT = "root" - + # Storage configuration prefix STORAGE_OPTIONS_PREFIX = "storage." - + def __init__(self, properties: Optional[Dict[str, str]] = None): """Initialize configuration from properties. - + Args: properties: Dictionary of configuration properties """ if properties is None: properties = {} - + # Store raw properties for pickling support self._properties = properties.copy() - + self._catalog_id = properties.get(self.CATALOG_ID) self._endpoint = properties.get(self.ENDPOINT) self._region = properties.get(self.REGION) @@ -672,71 +688,71 @@ def __init__(self, properties: Optional[Dict[str, str]] = None): self._session_token = properties.get(self.SESSION_TOKEN) self._profile_name = properties.get(self.PROFILE_NAME) self._root = properties.get(self.ROOT) - + # Parse max retries max_retries_str = properties.get(self.MAX_RETRIES) self._max_retries = int(max_retries_str) if max_retries_str else None - + self._retry_mode = properties.get(self.RETRY_MODE) - + # Extract storage options self._storage_options = self._extract_storage_options(properties) - + def _extract_storage_options(self, properties: Dict[str, str]) -> Dict[str, str]: """Extract storage configuration properties by removing the prefix.""" storage_options = {} for key, value in properties.items(): if key.startswith(self.STORAGE_OPTIONS_PREFIX): - storage_key = key[len(self.STORAGE_OPTIONS_PREFIX):] + storage_key = key[len(self.STORAGE_OPTIONS_PREFIX) :] storage_options[storage_key] = value return storage_options - + @property def catalog_id(self) -> Optional[str]: return self._catalog_id - + @property def endpoint(self) -> Optional[str]: return self._endpoint - + @property def region(self) -> Optional[str]: return self._region - + @property def access_key_id(self) -> Optional[str]: return self._access_key_id - + @property def secret_access_key(self) -> Optional[str]: return self._secret_access_key - + @property def session_token(self) -> Optional[str]: return self._session_token - + @property def profile_name(self) -> Optional[str]: return self._profile_name - + @property def max_retries(self) -> Optional[int]: return self._max_retries - + @property def retry_mode(self) -> Optional[str]: return self._retry_mode - + @property def root(self) -> Optional[str]: return self._root - + @property def storage_options(self) -> Dict[str, str]: """Get the storage configuration properties.""" return self._storage_options.copy() - + @property def properties(self) -> Dict[str, str]: """Get the raw properties dictionary.""" - return self._properties.copy() \ No newline at end of file + return self._properties.copy() diff --git a/python/src/lance_namespace_impls/hive2.py b/python/src/lance_namespace_impls/hive2.py index e2d93b0..d88fb58 100644 --- a/python/src/lance_namespace_impls/hive2.py +++ b/python/src/lance_namespace_impls/hive2.py @@ -10,34 +10,34 @@ Usage: from lance_namespace import connect - + # Connect to Hive Metastore namespace = connect("hive2", { "uri": "thrift://localhost:9083", "root": "/my/dir", # Or "s3://bucket/prefix" "ugi": "user:group1,group2" # Optional user/group info }) - + # List databases from lance_namespace import ListNamespacesRequest response = namespace.list_namespaces(ListNamespacesRequest()) - + # Create a table from lance_namespace import CreateTableRequest import pyarrow as pa import io - + data = pa.table({"col1": [1, 2, 3], "col2": ["a", "b", "c"]}) buf = io.BytesIO() with pa.ipc.new_stream(buf, data.schema) as writer: writer.write_table(data) - + request = CreateTableRequest( id=["my_database", "my_table"], mode="create" ) response = namespace.create_table(request, buf.getvalue()) - + # Register existing Lance table from lance_namespace import RegisterTableRequest request = RegisterTableRequest( @@ -53,14 +53,15 @@ client.pool-size (int): Size of the HMS client connection pool (default: 3) storage.* (str): Additional storage configurations to access table """ -from typing import Dict, List, Optional, Any -from urllib.parse import urlparse, unquote + +from typing import List, Optional +from urllib.parse import urlparse import os import logging try: - from hive_metastore.ThriftHiveMetastore import Client - from hive_metastore.ttypes import ( + from hive_metastore_client import HiveMetastoreClient as Client + from thrift_files.libraries.thrift_hive_metastore_client.ttypes import ( Database as HiveDatabase, Table as HiveTable, StorageDescriptor, @@ -71,8 +72,7 @@ InvalidOperationException, MetaException, ) - from thrift.protocol import TBinaryProtocol - from thrift.transport import TSocket, TTransport + HIVE_AVAILABLE = True except ImportError: HIVE_AVAILABLE = False @@ -116,9 +116,6 @@ DeregisterTableRequest, DeregisterTableResponse, TableExistsRequest, - JsonArrowSchema, - JsonArrowField, - JsonArrowDataType, ) logger = logging.getLogger(__name__) @@ -131,59 +128,50 @@ EXTERNAL_TABLE = "EXTERNAL_TABLE" -class HiveMetastoreClient: +class HiveMetastoreClientWrapper: """Helper class to manage Hive Metastore client connections.""" - + def __init__(self, uri: str, ugi: Optional[str] = None): if not HIVE_AVAILABLE: raise ImportError( "Hive dependencies not installed. Please install with: " "pip install 'lance-namespace[hive2]'" ) - + self._uri = uri self._ugi = ugi.split(":") if ugi else None - self._transport = None - self._client = None - self._init_client() - - def _init_client(self): - """Initialize the Thrift client connection.""" url_parts = urlparse(self._uri) - socket = TSocket.TSocket(url_parts.hostname, url_parts.port or 9083) - self._transport = TTransport.TBufferedTransport(socket) - protocol = TBinaryProtocol.TBinaryProtocol(self._transport) - self._client = Client(protocol) - - if not self._transport.isOpen(): - self._transport.open() - - if self._ugi: - self._client.set_ugi(*self._ugi) - + self._host = url_parts.hostname or "localhost" + self._port = url_parts.port or 9083 + self._client = None + def __enter__(self): """Enter context manager.""" - if not self._transport or not self._transport.isOpen(): - self._init_client() + self._client = Client(host=self._host, port=self._port) + self._client.open() + if self._ugi: + self._client.set_ugi(*self._ugi) return self._client - + def __exit__(self, exc_type, exc_val, exc_tb): """Exit context manager.""" - if self._transport and self._transport.isOpen(): - self._transport.close() - + if self._client: + self._client.close() + self._client = None + def close(self): """Close the client connection.""" - if self._transport and self._transport.isOpen(): - self._transport.close() + if self._client: + self._client.close() + self._client = None class Hive2Namespace(LanceNamespace): """Lance Hive2 Namespace implementation using Hive Metastore.""" - + def __init__(self, **properties): """Initialize the Hive2 namespace. - + Args: uri: The Hive Metastore URI (e.g., "thrift://localhost:9083") root: Storage root location of the lakehouse on Hive catalog (optional) @@ -197,17 +185,19 @@ def __init__(self, **properties): "Hive dependencies not installed. Please install with: " "pip install 'lance-namespace[hive2]'" ) - + self.uri = properties.get("uri", "thrift://localhost:9083") self.ugi = properties.get("ugi") self.root = properties.get("root", os.getcwd()) self.pool_size = int(properties.get("client.pool-size", "3")) # Extract storage properties - self.storage_properties = {k[8:]: v for k, v in properties.items() if k.startswith("storage.")} - + self.storage_properties = { + k[8:]: v for k, v in properties.items() if k.startswith("storage.") + } + # Store properties for pickling support self._properties = properties.copy() - + # Lazy initialization to support pickling self._client = None @@ -219,9 +209,9 @@ def namespace_id(self) -> str: def client(self): """Get the Hive client, initializing it if necessary.""" if self._client is None: - self._client = HiveMetastoreClient(self.uri, self.ugi) + self._client = HiveMetastoreClientWrapper(self.uri, self.ugi) return self._client - + def _normalize_identifier(self, identifier: List[str]) -> tuple: """Normalize identifier to (database, table) tuple.""" if len(identifier) == 1: @@ -230,15 +220,15 @@ def _normalize_identifier(self, identifier: List[str]) -> tuple: return (identifier[0], identifier[1]) else: raise ValueError(f"Invalid identifier: {identifier}") - + def _is_root_namespace(self, identifier: Optional[List[str]]) -> bool: """Check if the identifier refers to the root namespace.""" return not identifier or len(identifier) == 0 - + def _get_table_location(self, database: str, table: str) -> str: """Get the location for a table.""" return os.path.join(self.root, f"{database}.db", table) - + def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: """List all databases in the Hive Metastore.""" try: @@ -246,38 +236,40 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo if not self._is_root_namespace(request.id): # Non-root namespaces don't have children in Hive2 return ListNamespacesResponse(namespaces=[]) - + with self.client as client: databases = client.get_all_databases() # Return just database names as strings (excluding default) namespaces = [db for db in databases if db != "default"] - + return ListNamespacesResponse(namespaces=namespaces) except Exception as e: logger.error(f"Failed to list namespaces: {e}") raise - - def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: """Describe a database in the Hive Metastore.""" try: # Handle root namespace if self._is_root_namespace(request.id): properties = { "location": self.root, - "description": "Root namespace (Hive Metastore)" + "description": "Root namespace (Hive Metastore)", } if self.ugi: properties["ugi"] = self.ugi return DescribeNamespaceResponse(properties=properties) - + if len(request.id) != 1: raise ValueError(f"Invalid namespace identifier: {request.id}") - + database_name = request.id[0] - + with self.client as client: database = client.get_database(database_name) - + properties = {} if database.description: properties["comment"] = database.description @@ -287,54 +279,56 @@ def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNames properties["location"] = database.locationUri if database.parameters: properties.update(database.parameters) - - return DescribeNamespaceResponse( - properties=properties - ) + + return DescribeNamespaceResponse(properties=properties) except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): raise ValueError(f"Namespace {request.id} does not exist") logger.error(f"Failed to describe namespace {request.id}: {e}") raise - - def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: """Create a new database in the Hive Metastore.""" try: # Cannot create root namespace if self._is_root_namespace(request.id): raise ValueError("Root namespace already exists") - + if len(request.id) != 1: raise ValueError(f"Invalid namespace identifier: {request.id}") - + database_name = request.id[0] - + # Create database object if not HiveDatabase: raise ImportError("Hive dependencies not available") + + props = request.properties or {} database = HiveDatabase() database.name = database_name - database.description = request.properties.get("comment", "") - database.ownerName = request.properties.get("owner", os.getenv("USER", "")) - database.locationUri = request.properties.get( - "location", - os.path.join(self.root, f"{database_name}.db") + database.description = props.get("comment", "") + database.ownerName = props.get("owner", os.getenv("USER", "")) + database.locationUri = props.get( + "location", os.path.join(self.root, f"{database_name}.db") ) database.parameters = { - k: v for k, v in request.properties.items() + k: v + for k, v in props.items() if k not in ["comment", "owner", "location"] } - + with self.client as client: client.create_database(database) - + return CreateNamespaceResponse() except Exception as e: if AlreadyExistsException and isinstance(e, AlreadyExistsException): raise ValueError(f"Namespace {request.id} already exists") logger.error(f"Failed to create namespace {request.id}: {e}") raise - + def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a database from the Hive Metastore. Only RESTRICT mode is supported.""" try: @@ -362,19 +356,19 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse raise ValueError(f"Namespace {request.id} does not exist") logger.error(f"Failed to drop namespace {request.id}: {e}") raise - + def namespace_exists(self, request: NamespaceExistsRequest) -> None: """Check if a database exists in the Hive Metastore.""" try: # Root namespace always exists if self._is_root_namespace(request.id): return - + if len(request.id) != 1: raise ValueError(f"Invalid namespace identifier: {request.id}") - + database_name = request.id[0] - + with self.client as client: client.get_database(database_name) except Exception as e: @@ -382,22 +376,22 @@ def namespace_exists(self, request: NamespaceExistsRequest) -> None: raise ValueError(f"Namespace {request.id} does not exist") logger.error(f"Failed to check namespace existence {request.id}: {e}") raise - + def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a database.""" try: # Root namespace has no tables if self._is_root_namespace(request.id): return ListTablesResponse(tables=[]) - + if len(request.id) != 1: raise ValueError(f"Invalid namespace identifier: {request.id}") - + database_name = request.id[0] - + with self.client as client: table_names = client.get_all_tables(database_name) - + # Filter for Lance tables if needed tables = [] for table_name in table_names: @@ -405,21 +399,23 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: table = client.get_table(database_name, table_name) # Check if it's a Lance table (case insensitive) if table.parameters: - table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + table_type = table.parameters.get( + TABLE_TYPE_KEY, "" + ).lower() if table_type == LANCE_TABLE_FORMAT: # Return just table name, not full identifier tables.append(table_name) except Exception: # Skip tables we can't read continue - + return ListTablesResponse(tables=tables) except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): raise ValueError(f"Namespace {request.id} does not exist") logger.error(f"Failed to list tables in namespace {request.id}: {e}") raise - + def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table in the Hive Metastore. @@ -444,48 +440,58 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse raise ValueError(f"Table {request.id} has no location") return DescribeTableResponse( - location=location, - storage_options=self.config.storage_options + location=location, storage_options=self.storage_properties ) except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): raise ValueError(f"Table {request.id} does not exist") logger.error(f"Failed to describe table {request.id}: {e}") raise - + def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: """Register an existing Lance table in the Hive Metastore. - + Note: This will open the Lance dataset to get schema and version information. If you want to avoid opening the dataset, you can provide 'version' in properties. """ try: database, table_name = self._normalize_identifier(request.id) - + # Determine managed_by value - managed_by = request.properties.get(MANAGED_BY_KEY, "storage") if request.properties else "storage" - + managed_by = ( + request.properties.get(MANAGED_BY_KEY, "storage") + if request.properties + else "storage" + ) + # We always need to open the dataset to get schema for Hive columns dataset = lance.dataset(request.location) schema = dataset.schema - + # Only track version if managed_by is "impl" version = None if managed_by == "impl": # Get version from properties or dataset - version = request.properties.get(VERSION_KEY) if request.properties else None + version = ( + request.properties.get(VERSION_KEY) if request.properties else None + ) if version is None: version = str(dataset.version) - + # Create Hive table object if not HiveTable: raise ImportError("Hive dependencies not available") hive_table = HiveTable() hive_table.dbName = database hive_table.tableName = table_name - hive_table.owner = request.properties.get("owner", os.getenv("USER", "")) if request.properties else os.getenv("USER", "") + hive_table.owner = ( + request.properties.get("owner", os.getenv("USER", "")) + if request.properties + else os.getenv("USER", "") + ) # Use current time if file doesn't exist yet import time + current_time = int(time.time()) try: hive_table.createTime = int(os.path.getctime(request.location)) @@ -494,7 +500,7 @@ def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse hive_table.createTime = current_time hive_table.lastAccessTime = current_time hive_table.tableType = EXTERNAL_TABLE - + # Set storage descriptor if not StorageDescriptor: raise ImportError("Hive dependencies not available") @@ -504,53 +510,52 @@ def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse sd.outputFormat = "com.lancedb.lance.mapred.LanceOutputFormat" sd.compressed = False sd.cols = self._pyarrow_schema_to_hive_fields(schema) - + # Set SerDe info if not SerDeInfo: raise ImportError("Hive dependencies not available") serde = SerDeInfo() serde.serializationLib = "com.lancedb.lance.mapred.LanceSerDe" sd.serdeInfo = serde - + hive_table.sd = sd - + # Set table parameters per hive.md specification hive_table.parameters = { TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, MANAGED_BY_KEY: managed_by, } - + # Only set version if managed_by is "impl" if managed_by == "impl" and version is not None: hive_table.parameters[VERSION_KEY] = version - + if request.properties: # Add other properties but don't override the required ones for k, v in request.properties.items(): if k not in [TABLE_TYPE_KEY, MANAGED_BY_KEY, VERSION_KEY]: hive_table.parameters[k] = v - + with self.client as client: client.create_table(hive_table) - + return RegisterTableResponse( - location=request.location, - properties=request.properties + location=request.location, properties=request.properties ) except Exception as e: if AlreadyExistsException and isinstance(e, AlreadyExistsException): raise ValueError(f"Table {request.id} already exists") logger.error(f"Failed to register table {request.id}: {e}") raise - + def table_exists(self, request: TableExistsRequest) -> None: """Check if a table exists in the Hive Metastore.""" try: database, table_name = self._normalize_identifier(request.id) - + with self.client as client: table = client.get_table(database, table_name) - + # Check if it's a Lance table (case insensitive) if not table.parameters: raise ValueError(f"Table {request.id} is not a Lance table") @@ -562,7 +567,7 @@ def table_exists(self, request: TableExistsRequest) -> None: raise ValueError(f"Table {request.id} does not exist") logger.error(f"Failed to check table existence {request.id}: {e}") raise - + def drop_table(self, request: DropTableRequest) -> DropTableResponse: """Drop a table from the Hive Metastore. @@ -573,36 +578,40 @@ def drop_table(self, request: DropTableRequest) -> DropTableResponse: "drop_table is not supported. Use deregister_table to remove table metadata, " "then use Lance SDK to delete the actual table data if needed." ) - - def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableResponse: + + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: """Deregister a table from the Hive Metastore without deleting data.""" try: database, table_name = self._normalize_identifier(request.id) - + with self.client as client: # Get table to check if it's a Lance table table = client.get_table(database, table_name) - + # Check if it's a Lance table (case insensitive) if not table.parameters: raise ValueError(f"Table {request.id} is not a Lance table") table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() if table_type != LANCE_TABLE_FORMAT: raise ValueError(f"Table {request.id} is not a Lance table") - + location = table.sd.location if table.sd else None - + # Drop the table metadata only (don't delete data) client.drop_table(database, table_name, deleteData=False) - + return DeregisterTableResponse(location=location) except Exception as e: if NoSuchObjectException and isinstance(e, NoSuchObjectException): raise ValueError(f"Table {request.id} does not exist") logger.error(f"Failed to deregister table {request.id}: {e}") raise - - def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: + + def create_table( + self, request: CreateTableRequest, request_data: bytes + ) -> CreateTableResponse: """Create a new Lance table and register it in the Hive Metastore. This operation is not supported. Use create_empty_table to declare table metadata, @@ -612,70 +621,72 @@ def create_table(self, request: CreateTableRequest, request_data: bytes) -> Crea "create_table is not supported. Use create_empty_table to declare table metadata, " "then use Lance SDK to create the actual table data." ) - - def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: """Create an empty table (metadata only) in Hive metastore.""" try: database, table_name = self._normalize_identifier(request.id) - + # Determine table location location = request.location if not location: location = self._get_table_location(database, table_name) - + # Create a minimal schema for Hive (placeholder schema) if not FieldSchema: raise ImportError("Hive dependencies not available") - + fields = [ FieldSchema( - name='__placeholder_id', - type='bigint', - comment='Placeholder column for empty table' + name="__placeholder_id", + type="bigint", + comment="Placeholder column for empty table", ) ] - + # Create Hive table metadata without creating actual Lance dataset storage_descriptor = StorageDescriptor( cols=fields, location=location, - inputFormat='org.apache.hadoop.mapred.TextInputFormat', - outputFormat='org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat', + inputFormat="org.apache.hadoop.mapred.TextInputFormat", + outputFormat="org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", serdeInfo=SerDeInfo( - serializationLib='org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' - ) + serializationLib="org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe" + ), ) - + # Set table parameters to identify it as Lance table parameters = { TABLE_TYPE_KEY: "LANCE", MANAGED_BY_KEY: "storage", - 'empty_table': 'true', # Mark as empty table + "empty_table": "true", # Mark as empty table } - - if request.properties: + + if hasattr(request, "properties") and request.properties: parameters.update(request.properties) - + hive_table = HiveTable( tableName=table_name, dbName=database, sd=storage_descriptor, parameters=parameters, - tableType='EXTERNAL_TABLE' + tableType="EXTERNAL_TABLE", ) - + # Create table in Hive - with self.client_pool.get_client() as client: + with self.client as client: client.create_table(hive_table) - + return CreateEmptyTableResponse(location=location) - + except AlreadyExistsException: raise ValueError(f"Table {request.id} already exists") except Exception as e: logger.error(f"Failed to create empty table {request.id}: {e}") raise - + def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema]: """Convert PyArrow schema to Hive field schemas.""" fields = [] @@ -683,14 +694,10 @@ def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema] hive_type = self._pyarrow_type_to_hive_type(field.type) if not FieldSchema: raise ImportError("Hive dependencies not available") - hive_field = FieldSchema( - name=field.name, - type=hive_type, - comment="" - ) + hive_field = FieldSchema(name=field.name, type=hive_type, comment="") fields.append(hive_field) return fields - + def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: """Convert PyArrow data type to Hive type string.""" if pa.types.is_boolean(dtype): @@ -727,15 +734,21 @@ def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: return f"struct<{','.join(field_strs)}>" else: return "string" # Default to string for unknown types - + def __getstate__(self): """Prepare instance for pickling by excluding unpickleable objects.""" state = self.__dict__.copy() # Remove the unpickleable Hive client - state['_client'] = None + state["_client"] = None return state - + def __setstate__(self, state): """Restore instance from pickled state.""" self.__dict__.update(state) - # The Hive client will be re-initialized lazily via the property \ No newline at end of file + # The Hive client will be re-initialized lazily via the property + + def close(self): + """Close the Hive Metastore client connection.""" + if self._client is not None: + self._client.close() + self._client = None diff --git a/python/src/lance_namespace_impls/hive3.py b/python/src/lance_namespace_impls/hive3.py index 7e51b5d..0f259f1 100644 --- a/python/src/lance_namespace_impls/hive3.py +++ b/python/src/lance_namespace_impls/hive3.py @@ -39,14 +39,15 @@ client.pool-size (int): Size of the HMS client connection pool (default: 3) storage.* (str): Additional storage configurations """ -from typing import Dict, List, Optional, Any + +from typing import List, Optional from urllib.parse import urlparse import os import logging try: - from hive_metastore.ThriftHiveMetastore import Client - from hive_metastore.ttypes import ( + from hive_metastore_client import HiveMetastoreClient as Client + from thrift_files.libraries.thrift_hive_metastore_client.ttypes import ( Database as HiveDatabase, Table as HiveTable, StorageDescriptor, @@ -57,8 +58,7 @@ InvalidOperationException, MetaException, ) - from thrift.protocol import TBinaryProtocol - from thrift.transport import TSocket, TTransport + HIVE_AVAILABLE = True except ImportError: HIVE_AVAILABLE = False @@ -114,7 +114,7 @@ DEFAULT_CATALOG = "hive" -class Hive3MetastoreClient: +class Hive3MetastoreClientWrapper: """Helper class to manage Hive 3.x Metastore client connections.""" def __init__(self, uri: str, ugi: Optional[str] = None): @@ -126,39 +126,30 @@ def __init__(self, uri: str, ugi: Optional[str] = None): self._uri = uri self._ugi = ugi.split(":") if ugi else None - self._transport = None - self._client = None - self._init_client() - - def _init_client(self): - """Initialize the Thrift client connection.""" url_parts = urlparse(self._uri) - socket = TSocket.TSocket(url_parts.hostname, url_parts.port or 9083) - self._transport = TTransport.TBufferedTransport(socket) - protocol = TBinaryProtocol.TBinaryProtocol(self._transport) - self._client = Client(protocol) - - if not self._transport.isOpen(): - self._transport.open() - - if self._ugi: - self._client.set_ugi(*self._ugi) + self._host = url_parts.hostname or "localhost" + self._port = url_parts.port or 9083 + self._client = None def __enter__(self): """Enter context manager.""" - if not self._transport or not self._transport.isOpen(): - self._init_client() + self._client = Client(host=self._host, port=self._port) + self._client.open() + if self._ugi: + self._client.set_ugi(*self._ugi) return self._client def __exit__(self, exc_type, exc_val, exc_tb): """Exit context manager.""" - if self._transport and self._transport.isOpen(): - self._transport.close() + if self._client: + self._client.close() + self._client = None def close(self): """Close the client connection.""" - if self._transport and self._transport.isOpen(): - self._transport.close() + if self._client: + self._client.close() + self._client = None class Hive3Namespace(LanceNamespace): @@ -188,7 +179,9 @@ def __init__(self, **properties): self.ugi = properties.get("ugi") self.root = properties.get("root", os.getcwd()) self.pool_size = int(properties.get("client.pool-size", "3")) - self.storage_properties = {k[8:]: v for k, v in properties.items() if k.startswith("storage.")} + self.storage_properties = { + k[8:]: v for k, v in properties.items() if k.startswith("storage.") + } self._properties = properties.copy() self._client = None @@ -201,7 +194,7 @@ def namespace_id(self) -> str: def client(self): """Get the Hive client, initializing it if necessary.""" if self._client is None: - self._client = Hive3MetastoreClient(self.uri, self.ugi) + self._client = Hive3MetastoreClientWrapper(self.uri, self.ugi) return self._client def _normalize_identifier(self, identifier: List[str]) -> tuple: @@ -237,7 +230,11 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo with self.client as client: # Try to get catalogs if supported (Hive 3.x) try: - catalogs = client.get_catalogs().names if hasattr(client, 'get_catalogs') else [] + catalogs = ( + client.get_catalogs().names + if hasattr(client, "get_catalogs") + else [] + ) except Exception: # Fall back to default catalog catalogs = [DEFAULT_CATALOG] @@ -245,7 +242,9 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo elif len(ns_id) == 1: # List databases in catalog - catalog = ns_id[0].lower() + # Note: Hive 2.x Metastore API doesn't support catalog operations, + # so we ignore the catalog name and list all databases + _catalog = ns_id[0].lower() # noqa: F841 with self.client as client: try: databases = client.get_all_databases() @@ -263,13 +262,15 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo logger.error(f"Failed to list namespaces: {e}") raise - def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNamespaceResponse: + def describe_namespace( + self, request: DescribeNamespaceRequest + ) -> DescribeNamespaceResponse: """Describe a namespace (catalog or database).""" try: if self._is_root_namespace(request.id): properties = { "location": self.root, - "description": "Root namespace (Hive 3.x Metastore)" + "description": "Root namespace (Hive 3.x Metastore)", } if self.ugi: properties["ugi"] = self.ugi @@ -280,7 +281,7 @@ def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNames catalog_name = request.id[0].lower() properties = { "description": f"Catalog: {catalog_name}", - "catalog.location.uri": os.path.join(self.root, catalog_name) + "catalog.location.uri": os.path.join(self.root, catalog_name), } return DescribeNamespaceResponse(properties=properties) @@ -312,7 +313,9 @@ def describe_namespace(self, request: DescribeNamespaceRequest) -> DescribeNames logger.error(f"Failed to describe namespace {request.id}: {e}") raise - def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceResponse: + def create_namespace( + self, request: CreateNamespaceRequest + ) -> CreateNamespaceResponse: """Create a new namespace (catalog or database).""" try: if self._is_root_namespace(request.id): @@ -337,16 +340,26 @@ def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceRe database = HiveDatabase() database.name = database_name - database.description = request.properties.get("comment", "") if request.properties else "" - database.ownerName = request.properties.get("owner", os.getenv("USER", "")) if request.properties else os.getenv("USER", "") - database.locationUri = request.properties.get( - "location", - os.path.join(self.root, database_name) - ) if request.properties else os.path.join(self.root, database_name) + database.description = ( + request.properties.get("comment", "") if request.properties else "" + ) + database.ownerName = ( + request.properties.get("owner", os.getenv("USER", "")) + if request.properties + else os.getenv("USER", "") + ) + database.locationUri = ( + request.properties.get( + "location", os.path.join(self.root, database_name) + ) + if request.properties + else os.path.join(self.root, database_name) + ) if request.properties: database.parameters = { - k: v for k, v in request.properties.items() + k: v + for k, v in request.properties.items() if k not in ["comment", "owner", "location"] } @@ -359,7 +372,9 @@ def create_namespace(self, request: CreateNamespaceRequest) -> CreateNamespaceRe elif mode in ("exist_ok", "existok"): pass # OK to exist elif mode == "overwrite": - client.drop_database(database_name, deleteData=True, cascade=True) + client.drop_database( + database_name, deleteData=True, cascade=True + ) client.create_database(database) return CreateNamespaceResponse() @@ -438,7 +453,9 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: if self._is_root_namespace(request.id) or len(request.id) < 2: return ListTablesResponse(tables=[]) - catalog_name = request.id[0].lower() + # Note: Hive 2.x Metastore API doesn't support catalog operations, + # so we ignore the catalog name + _catalog_name = request.id[0].lower() # noqa: F841 database_name = request.id[1].lower() with self.client as client: @@ -450,7 +467,9 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: try: table = client.get_table(database_name, table_name) if table.parameters: - table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() + table_type = table.parameters.get( + TABLE_TYPE_KEY, "" + ).lower() if table_type == LANCE_TABLE_FORMAT: tables.append(table_name) except Exception: @@ -486,8 +505,7 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse raise ValueError(f"Table {request.id} has no location") return DescribeTableResponse( - location=location, - storage_options=self.config.storage_options + location=location, storage_options=self.storage_properties ) except Exception as e: @@ -501,14 +519,20 @@ def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse try: catalog, database, table_name = self._normalize_identifier(request.id) - managed_by = request.properties.get(MANAGED_BY_KEY, "storage") if request.properties else "storage" + managed_by = ( + request.properties.get(MANAGED_BY_KEY, "storage") + if request.properties + else "storage" + ) dataset = lance.dataset(request.location) schema = dataset.schema version = None if managed_by == "impl": - version = request.properties.get(VERSION_KEY) if request.properties else None + version = ( + request.properties.get(VERSION_KEY) if request.properties else None + ) if version is None: version = str(dataset.version) @@ -518,9 +542,14 @@ def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse hive_table = HiveTable() hive_table.dbName = database hive_table.tableName = table_name - hive_table.owner = request.properties.get("owner", os.getenv("USER", "")) if request.properties else os.getenv("USER", "") + hive_table.owner = ( + request.properties.get("owner", os.getenv("USER", "")) + if request.properties + else os.getenv("USER", "") + ) import time + current_time = int(time.time()) try: hive_table.createTime = int(os.path.getctime(request.location)) @@ -564,8 +593,7 @@ def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse client.create_table(hive_table) return RegisterTableResponse( - location=request.location, - properties=request.properties + location=request.location, properties=request.properties ) except Exception as e: @@ -605,7 +633,9 @@ def drop_table(self, request: DropTableRequest) -> DropTableResponse: "then use Lance SDK to delete the actual table data if needed." ) - def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableResponse: + def deregister_table( + self, request: DeregisterTableRequest + ) -> DeregisterTableResponse: """Deregister a table without deleting data.""" try: catalog, database, table_name = self._normalize_identifier(request.id) @@ -631,7 +661,9 @@ def deregister_table(self, request: DeregisterTableRequest) -> DeregisterTableRe logger.error(f"Failed to deregister table {request.id}: {e}") raise - def create_table(self, request: CreateTableRequest, request_data: bytes) -> CreateTableResponse: + def create_table( + self, request: CreateTableRequest, request_data: bytes + ) -> CreateTableResponse: """Create a new Lance table and register it. This operation is not supported. Use create_empty_table to declare table metadata, @@ -642,7 +674,9 @@ def create_table(self, request: CreateTableRequest, request_data: bytes) -> Crea "then use Lance SDK to create the actual table data." ) - def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTableResponse: + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: """Create an empty table (metadata only).""" try: catalog, database, table_name = self._normalize_identifier(request.id) @@ -656,29 +690,27 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab fields = [ FieldSchema( - name='__placeholder_id', - type='bigint', - comment='Placeholder column' + name="__placeholder_id", type="bigint", comment="Placeholder column" ) ] storage_descriptor = StorageDescriptor( cols=fields, location=location, - inputFormat='org.apache.hadoop.mapred.TextInputFormat', - outputFormat='org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat', + inputFormat="org.apache.hadoop.mapred.TextInputFormat", + outputFormat="org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat", serdeInfo=SerDeInfo( - serializationLib='org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' - ) + serializationLib="org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe" + ), ) parameters = { TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, MANAGED_BY_KEY: "storage", - 'empty_table': 'true', + "empty_table": "true", } - if request.properties: + if hasattr(request, "properties") and request.properties: parameters.update(request.properties) hive_table = HiveTable( @@ -686,7 +718,7 @@ def create_empty_table(self, request: CreateEmptyTableRequest) -> CreateEmptyTab dbName=database, sd=storage_descriptor, parameters=parameters, - tableType='EXTERNAL_TABLE' + tableType="EXTERNAL_TABLE", ) with self.client as client: @@ -707,11 +739,7 @@ def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema] hive_type = self._pyarrow_type_to_hive_type(field.type) if not FieldSchema: raise ImportError("Hive dependencies not available") - hive_field = FieldSchema( - name=field.name, - type=hive_type, - comment="" - ) + hive_field = FieldSchema(name=field.name, type=hive_type, comment="") fields.append(hive_field) return fields @@ -755,9 +783,15 @@ def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: def __getstate__(self): """Prepare instance for pickling.""" state = self.__dict__.copy() - state['_client'] = None + state["_client"] = None return state def __setstate__(self, state): """Restore instance from pickled state.""" self.__dict__.update(state) + + def close(self): + """Close the Hive Metastore client connection.""" + if self._client is not None: + self._client.close() + self._client = None diff --git a/python/src/lance_namespace_impls/iceberg.py b/python/src/lance_namespace_impls/iceberg.py index e2cb1a8..a9b81bf 100644 --- a/python/src/lance_namespace_impls/iceberg.py +++ b/python/src/lance_namespace_impls/iceberg.py @@ -42,7 +42,7 @@ logger = logging.getLogger(__name__) -NAMESPACE_SEPARATOR = "\x1F" +NAMESPACE_SEPARATOR = "\x1f" @dataclass @@ -179,7 +179,10 @@ def create_namespace( raise InvalidInputException("Namespace must have at least one level") try: - create_request = {"namespace": ns_id, "properties": request.properties or {}} + create_request = { + "namespace": ns_id, + "properties": request.properties or {}, + } response = self.rest_client.post("/namespaces", create_request) @@ -251,9 +254,7 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse if e.is_not_found(): return DropNamespaceResponse(properties={}) if e.is_conflict(): - raise InternalException( - f"Namespace not empty: {'.'.join(request.id)}" - ) + raise InternalException(f"Namespace not empty: {'.'.join(request.id)}") raise InternalException(f"Failed to drop namespace: {e}") except InvalidInputException: raise @@ -329,7 +330,7 @@ def create_empty_table( } namespace_path = self._encode_namespace(namespace) - response = self.rest_client.post( + self.rest_client.post( f"/namespaces/{namespace_path}/tables", create_request ) @@ -377,28 +378,26 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse ) if not response or "metadata" not in response: - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") metadata = response["metadata"] props = metadata.get("properties", {}) - if not props.get(self.TABLE_TYPE_KEY, "").lower() == self.TABLE_TYPE_LANCE.lower(): + if ( + not props.get(self.TABLE_TYPE_KEY, "").lower() + == self.TABLE_TYPE_LANCE.lower() + ): raise InvalidInputException( f"Table {'.'.join(request.id)} is not a Lance table" ) return DescribeTableResponse( - location=metadata.get("location"), - storage_options=props + location=metadata.get("location"), storage_options=props ) except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to describe table: {e}") except (TableNotFoundException, InvalidInputException): raise @@ -448,9 +447,7 @@ def deregister_table( except RestClientException as e: if e.is_not_found(): - raise TableNotFoundException( - f"Table not found: {'.'.join(request.id)}" - ) + raise TableNotFoundException(f"Table not found: {'.'.join(request.id)}") raise InternalException(f"Failed to deregister table: {e}") except (TableNotFoundException, InvalidInputException): raise diff --git a/python/src/lance_namespace_impls/rest_client.py b/python/src/lance_namespace_impls/rest_client.py index 9909579..d2634ad 100644 --- a/python/src/lance_namespace_impls/rest_client.py +++ b/python/src/lance_namespace_impls/rest_client.py @@ -118,7 +118,9 @@ def _make_request( ) if response.status >= 400: - raise RestClientException(response.status, response.data.decode("utf-8")) + raise RestClientException( + response.status, response.data.decode("utf-8") + ) if response.data: data = response.data.decode("utf-8") diff --git a/python/src/lance_namespace_impls/schema.py b/python/src/lance_namespace_impls/schema.py index 17c9c2a..20d7f6e 100644 --- a/python/src/lance_namespace_impls/schema.py +++ b/python/src/lance_namespace_impls/schema.py @@ -8,6 +8,7 @@ try: import pyarrow as pa + HAS_PYARROW = True except ImportError: pa = None @@ -22,72 +23,72 @@ def convert_json_arrow_schema_to_pyarrow(json_schema: JsonArrowSchema) -> "pa.Schema": """Convert JsonArrowSchema to PyArrow Schema. - + Args: json_schema: JsonArrowSchema from the client models - + Returns: PyArrow Schema object - + Raises: ImportError: If PyArrow is not available ValueError: If unsupported Arrow type is encountered """ if not HAS_PYARROW: raise ImportError("PyArrow is required for schema conversion") - + fields = [] for json_field in json_schema.fields: arrow_type = convert_json_arrow_type_to_pyarrow(json_field.type) field = pa.field(json_field.name, arrow_type, nullable=json_field.nullable) fields.append(field) - + return pa.schema(fields, metadata=json_schema.metadata) def convert_pyarrow_schema_to_json_arrow(schema: "pa.Schema") -> JsonArrowSchema: """Convert PyArrow schema to JSON Arrow schema. - + Args: schema: PyArrow schema to convert - + Returns: JsonArrowSchema object - + Raises: ImportError: If PyArrow is not available """ if not HAS_PYARROW: raise ImportError("PyArrow is required for schema conversion") - + fields = [] for field in schema: json_field = JsonArrowField( name=field.name, nullable=field.nullable, type=convert_pyarrow_type_to_json_arrow(field.type), - metadata=field.metadata + metadata=field.metadata, ) fields.append(json_field) - + return JsonArrowSchema(fields=fields) def convert_pyarrow_type_to_json_arrow(dtype: "pa.DataType") -> JsonArrowDataType: """Convert PyArrow data type to JSON Arrow data type. - + Args: dtype: PyArrow data type to convert - + Returns: JsonArrowDataType object - + Raises: ImportError: If PyArrow is not available """ if not HAS_PYARROW: raise ImportError("PyArrow is required for schema conversion") - + if pa.types.is_boolean(dtype): return JsonArrowDataType(name="bool") elif pa.types.is_int8(dtype): @@ -115,20 +116,14 @@ def convert_pyarrow_type_to_json_arrow(dtype: "pa.DataType") -> JsonArrowDataTyp elif pa.types.is_binary(dtype): return JsonArrowDataType(name="binary") elif pa.types.is_timestamp(dtype): - return JsonArrowDataType( - name="timestamp", - unit=dtype.unit, - timezone=dtype.tz - ) + return JsonArrowDataType(name="timestamp", unit=dtype.unit, timezone=dtype.tz) elif pa.types.is_date32(dtype): return JsonArrowDataType(name="date", unit="DAY") elif pa.types.is_date64(dtype): return JsonArrowDataType(name="date", unit="MILLISECOND") elif pa.types.is_decimal(dtype): return JsonArrowDataType( - name="decimal", - precision=dtype.precision, - scale=dtype.scale + name="decimal", precision=dtype.precision, scale=dtype.scale ) elif pa.types.is_list(dtype): return JsonArrowDataType(name="list") @@ -142,24 +137,24 @@ def convert_pyarrow_type_to_json_arrow(dtype: "pa.DataType") -> JsonArrowDataTyp def convert_json_arrow_type_to_pyarrow(json_type: JsonArrowDataType) -> "pa.DataType": """Convert JsonArrowDataType to PyArrow DataType. - + Args: json_type: JsonArrowDataType from the client models - + Returns: PyArrow DataType object - + Raises: ImportError: If PyArrow is not available ValueError: If unsupported Arrow type is encountered """ if not HAS_PYARROW: raise ImportError("PyArrow is required for type conversion") - + # Convert type name to lowercase but preserve timezone case type_name = json_type.type type_name_lower = type_name.lower() - + if type_name_lower == "null": return pa.null() elif type_name_lower in ["bool", "boolean"]: @@ -196,13 +191,14 @@ def convert_json_arrow_type_to_pyarrow(json_type: JsonArrowDataType) -> "pa.Data # Handle timestamp with timezone if "tz=" in type_name: tz = type_name.split("tz=")[1].rstrip("]") - return pa.timestamp('us', tz=tz) + return pa.timestamp("us", tz=tz) else: - return pa.timestamp('us') + return pa.timestamp("us") elif type_name_lower.startswith("decimal"): # Parse decimal(precision, scale) import re - match = re.match(r'decimal\((\d+),\s*(\d+)\)', type_name) + + match = re.match(r"decimal\((\d+),\s*(\d+)\)", type_name) if match: precision = int(match.group(1)) scale = int(match.group(2)) @@ -210,4 +206,4 @@ def convert_json_arrow_type_to_pyarrow(json_type: JsonArrowDataType) -> "pa.Data else: return pa.decimal128(38, 10) # Default precision/scale else: - raise ValueError(f"Unsupported Arrow type: {type_name_lower}") \ No newline at end of file + raise ValueError(f"Unsupported Arrow type: {type_name_lower}") diff --git a/python/tests/__init__.py b/python/tests/__init__.py index ce0f5ed..37e3b4c 100644 --- a/python/tests/__init__.py +++ b/python/tests/__init__.py @@ -1 +1 @@ -"""Tests for lance_namespace package.""" \ No newline at end of file +"""Tests for lance_namespace package.""" diff --git a/python/tests/test_glue.py b/python/tests/test_glue.py index 596001d..b215458 100644 --- a/python/tests/test_glue.py +++ b/python/tests/test_glue.py @@ -1,8 +1,9 @@ """ Tests for Lance Glue Namespace implementation. """ + import pytest -from unittest.mock import Mock, MagicMock, patch +from unittest.mock import MagicMock, patch import pyarrow as pa from lance_namespace_impls.glue import GlueNamespace, GlueNamespaceConfig @@ -25,7 +26,7 @@ @pytest.fixture def mock_boto3(): """Mock boto3 module.""" - with patch('lance_namespace_impls.glue.boto3') as mock: + with patch("lance_namespace_impls.glue.boto3") as mock: mock.Session.return_value.client.return_value = MagicMock() yield mock @@ -33,59 +34,56 @@ def mock_boto3(): @pytest.fixture def mock_lance(): """Mock lance module.""" - with patch('lance_namespace_impls.glue.lance') as mock: + with patch("lance_namespace_impls.glue.lance") as mock: yield mock @pytest.fixture def glue_namespace(mock_boto3, mock_lance): """Create a GlueNamespace instance with mocked dependencies.""" - properties = { - 'region': 'us-east-1', - 'catalog_id': '123456789012' - } + properties = {"region": "us-east-1", "catalog_id": "123456789012"} namespace = GlueNamespace(**properties) return namespace class TestGlueNamespaceConfig: """Test GlueNamespaceConfig class.""" - + def test_config_initialization(self): """Test configuration initialization.""" properties = { - 'catalog_id': '123456789012', - 'endpoint': 'https://glue.example.com', - 'region': 'us-west-2', - 'access_key_id': 'AKIAEXAMPLE', - 'secret_access_key': 'secret', - 'session_token': 'token', - 'profile_name': 'default', - 'max_retries': '5', - 'retry_mode': 'adaptive', - 'root': 's3://bucket/path', - 'storage.key1': 'value1', - 'storage.key2': 'value2', + "catalog_id": "123456789012", + "endpoint": "https://glue.example.com", + "region": "us-west-2", + "access_key_id": "AKIAEXAMPLE", + "secret_access_key": "secret", + "session_token": "token", + "profile_name": "default", + "max_retries": "5", + "retry_mode": "adaptive", + "root": "s3://bucket/path", + "storage.key1": "value1", + "storage.key2": "value2", } - + config = GlueNamespaceConfig(properties) - - assert config.catalog_id == '123456789012' - assert config.endpoint == 'https://glue.example.com' - assert config.region == 'us-west-2' - assert config.access_key_id == 'AKIAEXAMPLE' - assert config.secret_access_key == 'secret' - assert config.session_token == 'token' - assert config.profile_name == 'default' + + assert config.catalog_id == "123456789012" + assert config.endpoint == "https://glue.example.com" + assert config.region == "us-west-2" + assert config.access_key_id == "AKIAEXAMPLE" + assert config.secret_access_key == "secret" + assert config.session_token == "token" + assert config.profile_name == "default" assert config.max_retries == 5 - assert config.retry_mode == 'adaptive' - assert config.root == 's3://bucket/path' - assert config.storage_options == {'key1': 'value1', 'key2': 'value2'} - + assert config.retry_mode == "adaptive" + assert config.root == "s3://bucket/path" + assert config.storage_options == {"key1": "value1", "key2": "value2"} + def test_config_with_empty_properties(self): """Test configuration with empty properties.""" config = GlueNamespaceConfig({}) - + assert config.catalog_id is None assert config.endpoint is None assert config.region is None @@ -96,444 +94,482 @@ def test_config_with_empty_properties(self): class TestGlueNamespace: """Test GlueNamespace class.""" - + def test_initialization_without_boto3(self): """Test that initialization fails without boto3.""" - with patch('lance_namespace_impls.glue.HAS_BOTO3', False): + with patch("lance_namespace_impls.glue.HAS_BOTO3", False): with pytest.raises(ImportError, match="boto3 is required"): GlueNamespace() - + def test_list_namespaces(self, glue_namespace): """Test listing namespaces.""" glue_namespace.glue.get_databases.return_value = { - 'DatabaseList': [ - {'Name': 'db1'}, - {'Name': 'db2'}, + "DatabaseList": [ + {"Name": "db1"}, + {"Name": "db2"}, ] } - + request = ListNamespacesRequest() response = glue_namespace.list_namespaces(request) - - assert response.namespaces == ['db1', 'db2'] + + assert response.namespaces == ["db1", "db2"] glue_namespace.glue.get_databases.assert_called_once() - + def test_list_namespaces_with_pagination(self, glue_namespace): """Test listing namespaces with pagination.""" glue_namespace.glue.get_databases.side_effect = [ + {"DatabaseList": [{"Name": "db1"}], "NextToken": "token1"}, { - 'DatabaseList': [{'Name': 'db1'}], - 'NextToken': 'token1' + "DatabaseList": [{"Name": "db2"}], }, - { - 'DatabaseList': [{'Name': 'db2'}], - } ] - + request = ListNamespacesRequest() response = glue_namespace.list_namespaces(request) - - assert response.namespaces == ['db1', 'db2'] + + assert response.namespaces == ["db1", "db2"] assert glue_namespace.glue.get_databases.call_count == 2 - + def test_list_namespaces_hierarchical_not_supported(self, glue_namespace): """Test that hierarchical namespaces are not supported.""" - request = ListNamespacesRequest(id=['parent']) + request = ListNamespacesRequest(id=["parent"]) response = glue_namespace.list_namespaces(request) - + assert response.namespaces == [] glue_namespace.glue.get_databases.assert_not_called() - + def test_list_namespaces_root(self, glue_namespace): """Test listing namespaces at root level.""" glue_namespace.glue.get_databases.return_value = { - 'DatabaseList': [ - {'Name': 'db1'}, - {'Name': 'db2'}, + "DatabaseList": [ + {"Name": "db1"}, + {"Name": "db2"}, ] } - + # Empty id means root namespace request = ListNamespacesRequest(id=[]) response = glue_namespace.list_namespaces(request) - - assert response.namespaces == ['db1', 'db2'] + + assert response.namespaces == ["db1", "db2"] glue_namespace.glue.get_databases.assert_called_once() - + def test_create_namespace(self, glue_namespace): """Test creating a namespace.""" request = CreateNamespaceRequest( - id=['test_db'], - properties={'description': 'Test database', 'location': 's3://bucket/path'} + id=["test_db"], + properties={"description": "Test database", "location": "s3://bucket/path"}, ) - - response = glue_namespace.create_namespace(request) - + + glue_namespace.create_namespace(request) + glue_namespace.glue.create_database.assert_called_once() call_args = glue_namespace.glue.create_database.call_args - assert call_args[1]['DatabaseInput']['Name'] == 'test_db' - assert call_args[1]['DatabaseInput']['Description'] == 'Test database' - assert call_args[1]['DatabaseInput']['LocationUri'] == 's3://bucket/path' - + assert call_args[1]["DatabaseInput"]["Name"] == "test_db" + assert call_args[1]["DatabaseInput"]["Description"] == "Test database" + assert call_args[1]["DatabaseInput"]["LocationUri"] == "s3://bucket/path" + def test_create_namespace_root(self, glue_namespace): """Test creating root namespace fails.""" request = CreateNamespaceRequest(id=[]) - + with pytest.raises(RuntimeError, match="Root namespace already exists"): glue_namespace.create_namespace(request) - + glue_namespace.glue.create_database.assert_not_called() - + def test_create_namespace_already_exists(self, glue_namespace): """Test creating a namespace that already exists.""" + # Create a custom exception with the right name class AlreadyExistsException(Exception): pass - + glue_namespace.glue.exceptions.AlreadyExistsException = AlreadyExistsException - glue_namespace.glue.create_database.side_effect = AlreadyExistsException("Already exists") - - request = CreateNamespaceRequest(id=['test_db']) - + glue_namespace.glue.create_database.side_effect = AlreadyExistsException( + "Already exists" + ) + + request = CreateNamespaceRequest(id=["test_db"]) + with pytest.raises(RuntimeError, match="Namespace already exists"): glue_namespace.create_namespace(request) - + def test_describe_namespace_root(self, glue_namespace): """Test describing root namespace.""" request = DescribeNamespaceRequest(id=[]) response = glue_namespace.describe_namespace(request) - - assert response.properties['description'] == 'Root Glue catalog namespace' + + assert response.properties["description"] == "Root Glue catalog namespace" glue_namespace.glue.get_database.assert_not_called() - + def test_describe_namespace(self, glue_namespace): """Test describing a namespace.""" glue_namespace.glue.get_database.return_value = { - 'Database': { - 'Name': 'test_db', - 'Description': 'Test database', - 'LocationUri': 's3://bucket/path', - 'Parameters': {'key': 'value'} + "Database": { + "Name": "test_db", + "Description": "Test database", + "LocationUri": "s3://bucket/path", + "Parameters": {"key": "value"}, } } - - request = DescribeNamespaceRequest(id=['test_db']) + + request = DescribeNamespaceRequest(id=["test_db"]) response = glue_namespace.describe_namespace(request) - - assert response.properties['description'] == 'Test database' - assert response.properties['location'] == 's3://bucket/path' - assert response.properties['key'] == 'value' - + + assert response.properties["description"] == "Test database" + assert response.properties["location"] == "s3://bucket/path" + assert response.properties["key"] == "value" + def test_drop_namespace_root(self, glue_namespace): """Test dropping root namespace fails.""" request = DropNamespaceRequest(id=[]) - + with pytest.raises(RuntimeError, match="Cannot drop root namespace"): glue_namespace.drop_namespace(request) - + glue_namespace.glue.get_tables.assert_not_called() glue_namespace.glue.delete_database.assert_not_called() - + def test_drop_namespace(self, glue_namespace): """Test dropping an empty namespace.""" - glue_namespace.glue.get_tables.return_value = {'TableList': []} - - request = DropNamespaceRequest(id=['test_db']) - response = glue_namespace.drop_namespace(request) - - glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName='test_db') - glue_namespace.glue.delete_database.assert_called_once_with(Name='test_db') - + glue_namespace.glue.get_tables.return_value = {"TableList": []} + + request = DropNamespaceRequest(id=["test_db"]) + glue_namespace.drop_namespace(request) + + glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName="test_db") + glue_namespace.glue.delete_database.assert_called_once_with(Name="test_db") + def test_drop_namespace_not_empty(self, glue_namespace): """Test dropping a non-empty namespace.""" glue_namespace.glue.get_tables.return_value = { - 'TableList': [{'Name': 'table1'}] + "TableList": [{"Name": "table1"}] } - - request = DropNamespaceRequest(id=['test_db']) - + + request = DropNamespaceRequest(id=["test_db"]) + with pytest.raises(RuntimeError, match="Cannot drop non-empty namespace"): glue_namespace.drop_namespace(request) - + def test_namespace_exists_root(self, glue_namespace): """Test checking if root namespace exists.""" request = NamespaceExistsRequest(id=[]) glue_namespace.namespace_exists(request) # Should not raise - + glue_namespace.glue.get_database.assert_not_called() - + def test_namespace_exists(self, glue_namespace): """Test checking if a namespace exists.""" - glue_namespace.glue.get_database.return_value = {'Database': {'Name': 'test_db'}} - - request = NamespaceExistsRequest(id=['test_db']) + glue_namespace.glue.get_database.return_value = { + "Database": {"Name": "test_db"} + } + + request = NamespaceExistsRequest(id=["test_db"]) glue_namespace.namespace_exists(request) # Should not raise - - glue_namespace.glue.get_database.assert_called_once_with(Name='test_db') - + + glue_namespace.glue.get_database.assert_called_once_with(Name="test_db") + def test_namespace_not_exists(self, glue_namespace): """Test checking if a namespace doesn't exist.""" + # Create a custom exception with the right name class EntityNotFoundException(Exception): pass - + glue_namespace.glue.exceptions.EntityNotFoundException = EntityNotFoundException - glue_namespace.glue.get_database.side_effect = EntityNotFoundException("Not found") - - request = NamespaceExistsRequest(id=['test_db']) - + glue_namespace.glue.get_database.side_effect = EntityNotFoundException( + "Not found" + ) + + request = NamespaceExistsRequest(id=["test_db"]) + with pytest.raises(RuntimeError, match="Namespace does not exist"): glue_namespace.namespace_exists(request) - + def test_list_tables_root(self, glue_namespace): """Test listing tables at root namespace returns empty.""" request = ListTablesRequest(id=[]) response = glue_namespace.list_tables(request) - + assert response.tables == [] glue_namespace.glue.get_tables.assert_not_called() - + def test_list_tables(self, glue_namespace): """Test listing tables in a namespace.""" glue_namespace.glue.get_tables.return_value = { - 'TableList': [ - {'Name': 'table1', 'Parameters': {'table_type': 'LANCE'}}, - {'Name': 'table2', 'Parameters': {'table_type': 'LANCE'}}, - {'Name': 'table3', 'Parameters': {'table_type': 'HIVE'}}, # Not a Lance table + "TableList": [ + {"Name": "table1", "Parameters": {"table_type": "LANCE"}}, + {"Name": "table2", "Parameters": {"table_type": "LANCE"}}, + { + "Name": "table3", + "Parameters": {"table_type": "HIVE"}, + }, # Not a Lance table ] } - - request = ListTablesRequest(id=['test_db']) + + request = ListTablesRequest(id=["test_db"]) response = glue_namespace.list_tables(request) - - assert response.tables == ['table1', 'table2'] - glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName='test_db') - + + assert response.tables == ["table1", "table2"] + glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName="test_db") + def test_create_table_not_supported(self, glue_namespace, mock_lance): """Test that create_table raises NotImplementedError.""" - request = CreateTableRequest(id=['test_db', 'test_table']) + request = CreateTableRequest(id=["test_db", "test_table"]) with pytest.raises(NotImplementedError, match="create_table is not supported"): glue_namespace.create_table(request, b"test_data") def test_drop_table_not_supported(self, glue_namespace, mock_lance): """Test that drop_table raises NotImplementedError.""" - request = DropTableRequest(id=['test_db', 'test_table']) + request = DropTableRequest(id=["test_db", "test_table"]) with pytest.raises(NotImplementedError, match="drop_table is not supported"): glue_namespace.drop_table(request) - + def test_deregister_table(self, glue_namespace, mock_lance): """Test deregistering a table (only removes from Glue, keeps Lance dataset).""" - request = DeregisterTableRequest(id=['test_db', 'test_table']) - response = glue_namespace.deregister_table(request) - + request = DeregisterTableRequest(id=["test_db", "test_table"]) + glue_namespace.deregister_table(request) + # Verify only Glue table was deleted (no Lance operations) mock_lance.dataset.assert_not_called() glue_namespace.glue.delete_table.assert_called_once_with( - DatabaseName='test_db', - Name='test_table' + DatabaseName="test_db", Name="test_table" ) - + def test_describe_table(self, glue_namespace): """Test describing a table.""" glue_namespace.glue.get_table.return_value = { - 'Table': { - 'Name': 'test_table', - 'Parameters': {'table_type': 'LANCE'}, - 'StorageDescriptor': {'Location': 's3://bucket/table.lance'} + "Table": { + "Name": "test_table", + "Parameters": {"table_type": "LANCE"}, + "StorageDescriptor": {"Location": "s3://bucket/table.lance"}, } } - - request = DescribeTableRequest(id=['test_db', 'test_table']) + + request = DescribeTableRequest(id=["test_db", "test_table"]) response = glue_namespace.describe_table(request) - - assert response.location == 's3://bucket/table.lance' - + + assert response.location == "s3://bucket/table.lance" + def test_describe_table_not_lance(self, glue_namespace): """Test describing a non-Lance table.""" glue_namespace.glue.get_table.return_value = { - 'Table': { - 'Name': 'test_table', - 'Parameters': {'table_type': 'HIVE'}, - 'StorageDescriptor': {'Location': 's3://bucket/table'} + "Table": { + "Name": "test_table", + "Parameters": {"table_type": "HIVE"}, + "StorageDescriptor": {"Location": "s3://bucket/table"}, } } - - request = DescribeTableRequest(id=['test_db', 'test_table']) - + + request = DescribeTableRequest(id=["test_db", "test_table"]) + with pytest.raises(RuntimeError, match="Table is not a Lance table"): glue_namespace.describe_table(request) - + def test_register_table(self, glue_namespace, mock_lance): """Test registering an existing table.""" # Mock Lance dataset mock_dataset = MagicMock() - mock_dataset.schema = pa.schema([ - pa.field('id', pa.int64()), - pa.field('name', pa.string()), - ]) + mock_dataset.schema = pa.schema( + [ + pa.field("id", pa.int64()), + pa.field("name", pa.string()), + ] + ) mock_lance.dataset.return_value = mock_dataset - + request = RegisterTableRequest( - id=['test_db', 'test_table'], - location='s3://bucket/existing_table.lance' + id=["test_db", "test_table"], location="s3://bucket/existing_table.lance" ) - + response = glue_namespace.register_table(request) - - assert response.location == 's3://bucket/existing_table.lance' - + + assert response.location == "s3://bucket/existing_table.lance" + # Verify Lance dataset was read mock_lance.dataset.assert_called_once_with( - 's3://bucket/existing_table.lance', - storage_options={} + "s3://bucket/existing_table.lance", storage_options={} ) - + # Verify Glue table was created glue_namespace.glue.create_table.assert_called_once() call_args = glue_namespace.glue.create_table.call_args - assert call_args[1]['DatabaseName'] == 'test_db' - assert call_args[1]['TableInput']['Name'] == 'test_table' - assert call_args[1]['TableInput']['Parameters']['table_type'] == 'LANCE' - + assert call_args[1]["DatabaseName"] == "test_db" + assert call_args[1]["TableInput"]["Name"] == "test_table" + assert call_args[1]["TableInput"]["Parameters"]["table_type"] == "LANCE" + def test_table_exists(self, glue_namespace): """Test checking if a table exists.""" glue_namespace.glue.get_table.return_value = { - 'Table': { - 'Name': 'test_table', - 'Parameters': {'table_type': 'LANCE'} - } + "Table": {"Name": "test_table", "Parameters": {"table_type": "LANCE"}} } - - request = TableExistsRequest(id=['test_db', 'test_table']) + + request = TableExistsRequest(id=["test_db", "test_table"]) glue_namespace.table_exists(request) # Should not raise - + glue_namespace.glue.get_table.assert_called_once_with( - DatabaseName='test_db', - Name='test_table' + DatabaseName="test_db", Name="test_table" ) - + def test_table_not_exists(self, glue_namespace): """Test checking if a table doesn't exist.""" + # Create a custom exception with the right name class EntityNotFoundException(Exception): pass - + glue_namespace.glue.exceptions.EntityNotFoundException = EntityNotFoundException glue_namespace.glue.get_table.side_effect = EntityNotFoundException("Not found") - - request = TableExistsRequest(id=['test_db', 'test_table']) - + + request = TableExistsRequest(id=["test_db", "test_table"]) + with pytest.raises(RuntimeError, match="Table does not exist"): glue_namespace.table_exists(request) - + def test_parse_table_identifier(self, glue_namespace): """Test parsing table identifier.""" - db, table = glue_namespace._parse_table_identifier(['db', 'table']) - assert db == 'db' - assert table == 'table' - + db, table = glue_namespace._parse_table_identifier(["db", "table"]) + assert db == "db" + assert table == "table" + with pytest.raises(ValueError, match="exactly 2 parts"): - glue_namespace._parse_table_identifier(['db']) - + glue_namespace._parse_table_identifier(["db"]) + with pytest.raises(ValueError, match="exactly 2 parts"): - glue_namespace._parse_table_identifier(['db', 'schema', 'table']) - + glue_namespace._parse_table_identifier(["db", "schema", "table"]) + def test_is_lance_table(self, glue_namespace): """Test checking if a Glue table is a Lance table.""" - lance_table = {'Parameters': {'table_type': 'LANCE'}} + lance_table = {"Parameters": {"table_type": "LANCE"}} assert glue_namespace._is_lance_table(lance_table) is True - - lance_table_lower = {'Parameters': {'table_type': 'lance'}} + + lance_table_lower = {"Parameters": {"table_type": "lance"}} assert glue_namespace._is_lance_table(lance_table_lower) is True - - hive_table = {'Parameters': {'table_type': 'HIVE'}} + + hive_table = {"Parameters": {"table_type": "HIVE"}} assert glue_namespace._is_lance_table(hive_table) is False - + no_params = {} assert glue_namespace._is_lance_table(no_params) is False - + def test_pyarrow_type_conversions(self, glue_namespace): """Test PyArrow to Glue type conversions.""" # Test basic types - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.bool_()) == 'boolean' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int32()) == 'int' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int64()) == 'bigint' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.float32()) == 'float' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.float64()) == 'double' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.string()) == 'string' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.binary()) == 'binary' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.date32()) == 'date' - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.timestamp('us')) == 'timestamp' - + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.bool_()) == "boolean" + ) + assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int32()) == "int" + assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int64()) == "bigint" + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.float32()) == "float" + ) + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.float64()) == "double" + ) + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.string()) == "string" + ) + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.binary()) == "binary" + ) + assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.date32()) == "date" + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.timestamp("us")) + == "timestamp" + ) + # Test complex types - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.list_(pa.int32())) == 'array' - assert glue_namespace._convert_pyarrow_type_to_glue_type( - pa.struct([pa.field('a', pa.int32()), pa.field('b', pa.string())]) - ) == 'struct' - assert glue_namespace._convert_pyarrow_type_to_glue_type( - pa.map_(pa.string(), pa.int32()) - ) == 'map' - + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.list_(pa.int32())) + == "array" + ) + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type( + pa.struct([pa.field("a", pa.int32()), pa.field("b", pa.string())]) + ) + == "struct" + ) + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type( + pa.map_(pa.string(), pa.int32()) + ) + == "map" + ) + # Test decimal - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.decimal128(10, 2)) == 'decimal(10,2)' - + assert ( + glue_namespace._convert_pyarrow_type_to_glue_type(pa.decimal128(10, 2)) + == "decimal(10,2)" + ) + def test_pyarrow_schema_to_glue_columns(self, glue_namespace): """Test conversion of PyArrow schema to Glue column definitions.""" - schema = pa.schema([ - pa.field('id', pa.int64()), - pa.field('name', pa.string()), - pa.field('scores', pa.list_(pa.float32())), - pa.field('metadata', pa.struct([ - pa.field('created', pa.timestamp('us')), - pa.field('version', pa.int32()) - ])) - ]) - + schema = pa.schema( + [ + pa.field("id", pa.int64()), + pa.field("name", pa.string()), + pa.field("scores", pa.list_(pa.float32())), + pa.field( + "metadata", + pa.struct( + [ + pa.field("created", pa.timestamp("us")), + pa.field("version", pa.int32()), + ] + ), + ), + ] + ) + columns = glue_namespace._convert_pyarrow_schema_to_glue_columns(schema) - + assert len(columns) == 4 - assert columns[0] == {'Name': 'id', 'Type': 'bigint'} - assert columns[1] == {'Name': 'name', 'Type': 'string'} - assert columns[2] == {'Name': 'scores', 'Type': 'array'} - assert columns[3] == {'Name': 'metadata', 'Type': 'struct'} - + assert columns[0] == {"Name": "id", "Type": "bigint"} + assert columns[1] == {"Name": "name", "Type": "string"} + assert columns[2] == {"Name": "scores", "Type": "array"} + assert columns[3] == { + "Name": "metadata", + "Type": "struct", + } + def test_pickle_support(self, mock_boto3): """Test that GlueNamespace can be pickled and unpickled for Ray compatibility.""" import pickle - + # Create a GlueNamespace instance properties = { - 'region': 'us-east-1', - 'catalog_id': '123456789012', - 'endpoint': 'https://glue.example.com', - 'storage.access_key_id': 'test-key', - 'storage.secret_access_key': 'test-secret' + "region": "us-east-1", + "catalog_id": "123456789012", + "endpoint": "https://glue.example.com", + "storage.access_key_id": "test-key", + "storage.secret_access_key": "test-secret", } namespace = GlueNamespace(**properties) - + # Test pickling pickled = pickle.dumps(namespace) assert pickled is not None - + # Test unpickling restored = pickle.loads(pickled) assert isinstance(restored, GlueNamespace) - + # Verify configuration is preserved - assert restored.config.region == 'us-east-1' - assert restored.config.catalog_id == '123456789012' - assert restored.config.endpoint == 'https://glue.example.com' - assert restored.config.storage_options['access_key_id'] == 'test-key' - assert restored.config.storage_options['secret_access_key'] == 'test-secret' - + assert restored.config.region == "us-east-1" + assert restored.config.catalog_id == "123456789012" + assert restored.config.endpoint == "https://glue.example.com" + assert restored.config.storage_options["access_key_id"] == "test-key" + assert restored.config.storage_options["secret_access_key"] == "test-secret" + # Verify glue client is None after unpickling (will be lazily initialized) assert restored._glue is None - + # Test that glue client can be re-initialized after unpickling # This will create a new mock client when accessed client = restored.glue assert client is not None assert restored._glue is not None - diff --git a/python/tests/test_hive2.py b/python/tests/test_hive2.py index 764a8db..2252881 100644 --- a/python/tests/test_hive2.py +++ b/python/tests/test_hive2.py @@ -1,10 +1,11 @@ """ Tests for Lance Hive2 Namespace implementation. """ + import os import pytest import tempfile -from unittest.mock import Mock, MagicMock, patch +from unittest.mock import MagicMock, patch import pyarrow as pa from lance_namespace_impls.hive2 import Hive2Namespace @@ -27,7 +28,9 @@ def mock_hive_client(): """Create a mock Hive client.""" with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client_class: + with patch( + "lance_namespace_impls.hive2.HiveMetastoreClientWrapper" + ) as mock_client_class: mock_client = MagicMock() mock_client_class.return_value = mock_client yield mock_client @@ -37,10 +40,7 @@ def mock_hive_client(): def hive_namespace(mock_hive_client): """Create a Hive2Namespace instance with mocked client.""" with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): - namespace = Hive2Namespace( - uri="thrift://localhost:9083", - root="/tmp/warehouse" - ) + namespace = Hive2Namespace(uri="thrift://localhost:9083", root="/tmp/warehouse") namespace._client = mock_hive_client return namespace @@ -51,11 +51,13 @@ class TestHive2Namespace: def test_initialization(self): """Test namespace initialization.""" with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client: + with patch( + "lance_namespace_impls.hive2.HiveMetastoreClientWrapper" + ) as mock_client: namespace = Hive2Namespace( uri="thrift://localhost:9083", root="/tmp/warehouse", - ugi="user:group1,group2" + ugi="user:group1,group2", ) assert namespace.uri == "thrift://localhost:9083" @@ -67,26 +69,32 @@ def test_initialization(self): # Access the client property to trigger initialization _ = namespace.client - mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") + mock_client.assert_called_once_with( + "thrift://localhost:9083", "user:group1,group2" + ) def test_initialization_without_hive_deps(self): """Test that initialization fails gracefully without Hive dependencies.""" with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", False): with pytest.raises(ImportError, match="Hive dependencies not installed"): Hive2Namespace(uri="thrift://localhost:9083") - + def test_list_namespaces(self, hive_namespace, mock_hive_client): """Test listing namespaces (databases).""" mock_client_instance = MagicMock() - mock_client_instance.get_all_databases.return_value = ["default", "test_db", "prod_db"] + mock_client_instance.get_all_databases.return_value = [ + "default", + "test_db", + "prod_db", + ] mock_hive_client.__enter__.return_value = mock_client_instance - + request = ListNamespacesRequest() response = hive_namespace.list_namespaces(request) - + assert response.namespaces == ["test_db", "prod_db"] mock_client_instance.get_all_databases.assert_called_once() - + def test_describe_namespace(self, hive_namespace, mock_hive_client): """Test describing a namespace (database).""" mock_database = MagicMock() @@ -94,112 +102,122 @@ def test_describe_namespace(self, hive_namespace, mock_hive_client): mock_database.ownerName = "test_user" mock_database.locationUri = "/tmp/warehouse/test_db.db" mock_database.parameters = {"key": "value"} - + mock_client_instance = MagicMock() mock_client_instance.get_database.return_value = mock_database mock_hive_client.__enter__.return_value = mock_client_instance - + request = DescribeNamespaceRequest(id=["test_db"]) response = hive_namespace.describe_namespace(request) - + # Response doesn't include id, only properties assert response.properties["comment"] == "Test database" assert response.properties["owner"] == "test_user" assert response.properties["location"] == "/tmp/warehouse/test_db.db" assert response.properties["key"] == "value" mock_client_instance.get_database.assert_called_once_with("test_db") - + def test_create_namespace(self, hive_namespace, mock_hive_client): """Test creating a namespace (database).""" mock_client_instance = MagicMock() mock_hive_client.__enter__.return_value = mock_client_instance - + # Mock HiveDatabase class with patch("lance_namespace_impls.hive2.HiveDatabase") as mock_hive_db_class: mock_hive_db = MagicMock() mock_hive_db_class.return_value = mock_hive_db - + request = CreateNamespaceRequest( id=["test_db"], properties={ "comment": "Test database", "owner": "test_user", - "location": "/custom/location" - } + "location": "/custom/location", + }, ) - response = hive_namespace.create_namespace(request) - - # Response doesn't include id + hive_namespace.create_namespace(request) mock_client_instance.create_database.assert_called_once_with(mock_hive_db) - + # Verify the database object properties were set assert mock_hive_db.name == "test_db" assert mock_hive_db.description == "Test database" assert mock_hive_db.ownerName == "test_user" assert mock_hive_db.locationUri == "/custom/location" - + def test_drop_namespace(self, hive_namespace, mock_hive_client): """Test dropping a namespace (database).""" mock_client_instance = MagicMock() mock_client_instance.get_all_tables.return_value = [] mock_hive_client.__enter__.return_value = mock_client_instance - + request = DropNamespaceRequest(id=["test_db"]) - response = hive_namespace.drop_namespace(request) - + hive_namespace.drop_namespace(request) + mock_client_instance.get_all_tables.assert_called_once_with("test_db") mock_client_instance.drop_database.assert_called_once_with( "test_db", deleteData=True, cascade=False ) - - def test_drop_namespace_cascade(self, hive_namespace, mock_hive_client): - """Test dropping a non-empty namespace with cascade.""" + + def test_drop_namespace_not_empty_fails(self, hive_namespace, mock_hive_client): + """Test that dropping a non-empty namespace fails (only RESTRICT mode is supported).""" mock_client_instance = MagicMock() mock_client_instance.get_all_tables.return_value = ["table1", "table2"] mock_hive_client.__enter__.return_value = mock_client_instance - - request = DropNamespaceRequest(id=["test_db"], behavior="CASCADE") - response = hive_namespace.drop_namespace(request) - - mock_client_instance.drop_database.assert_called_once_with( - "test_db", deleteData=True, cascade=True - ) - + + request = DropNamespaceRequest(id=["test_db"]) + + # Should fail because namespace is not empty and CASCADE is not supported + with pytest.raises(ValueError, match="is not empty"): + hive_namespace.drop_namespace(request) + def test_namespace_exists(self, hive_namespace, mock_hive_client): """Test checking if a namespace exists.""" mock_client_instance = MagicMock() mock_hive_client.__enter__.return_value = mock_client_instance - + request = NamespaceExistsRequest(id=["test_db"]) hive_namespace.namespace_exists(request) - + mock_client_instance.get_database.assert_called_once_with("test_db") - + def test_list_tables(self, hive_namespace, mock_hive_client): """Test listing tables in a namespace.""" mock_table1 = MagicMock() mock_table1.parameters = {"table_type": "lance"} - + mock_table2 = MagicMock() mock_table2.parameters = {"other_type": "OTHER"} - + mock_table3 = MagicMock() mock_table3.parameters = {"table_type": "lance"} - + mock_client_instance = MagicMock() - mock_client_instance.get_all_tables.return_value = ["table1", "table2", "table3"] - mock_client_instance.get_table.side_effect = [mock_table1, mock_table2, mock_table3] + mock_client_instance.get_all_tables.return_value = [ + "table1", + "table2", + "table3", + ] + mock_client_instance.get_table.side_effect = [ + mock_table1, + mock_table2, + mock_table3, + ] mock_hive_client.__enter__.return_value = mock_client_instance - + request = ListTablesRequest(id=["test_db"]) response = hive_namespace.list_tables(request) - + # Should only return Lance table names assert response.tables == ["table1", "table3"] mock_client_instance.get_all_tables.assert_called_once_with("test_db") - + def test_describe_table(self, hive_namespace, mock_hive_client): - """Test describing a table returns Hive metadata without opening Lance dataset.""" + """Test describing a table returns location and storage_options only. + + Note: load_detailed_metadata=false is the only supported mode, which means + only location and storage_options are returned. Other fields (version, schema, etc.) + are not populated. + """ mock_table = MagicMock() mock_table.sd.location = "/tmp/warehouse/test_db.db/test_table" mock_table.owner = "table_owner" @@ -216,38 +234,46 @@ def test_describe_table(self, hive_namespace, mock_hive_client): response = hive_namespace.describe_table(request) assert response.location == "/tmp/warehouse/test_db.db/test_table" - assert response.version == 42 - assert response.var_schema is None + # Only location and storage_options are returned (load_detailed_metadata=false) + assert ( + response.storage_options == {} + ) # Empty since no storage.* properties configured mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - + def test_register_table(self, hive_namespace, mock_hive_client): """Test registering a Lance table.""" with tempfile.TemporaryDirectory() as tmpdir: # Create a mock Lance dataset table_path = os.path.join(tmpdir, "test_table") - + # Create sample data - data = pa.table({ - "id": [1, 2, 3], - "name": ["Alice", "Bob", "Charlie"] - }) - - with patch("lance_namespace_impls.hive2.lance.dataset") as mock_dataset_func: + data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) + + with patch( + "lance_namespace_impls.hive2.lance.dataset" + ) as mock_dataset_func: mock_dataset = MagicMock() mock_dataset.schema = data.schema mock_dataset.version = 1 mock_dataset_func.return_value = mock_dataset - + mock_client_instance = MagicMock() mock_hive_client.__enter__.return_value = mock_client_instance - + # Mock all Hive classes - with patch("lance_namespace_impls.hive2.HiveTable") as mock_hive_table_class, \ - patch("lance_namespace_impls.hive2.StorageDescriptor") as mock_sd_class, \ - patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, \ - patch("lance_namespace_impls.hive2.FieldSchema") as mock_field_class: - + with ( + patch( + "lance_namespace_impls.hive2.HiveTable" + ) as mock_hive_table_class, + patch( + "lance_namespace_impls.hive2.StorageDescriptor" + ) as mock_sd_class, + patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, + patch( + "lance_namespace_impls.hive2.FieldSchema" + ) as mock_field_class, + ): mock_hive_table = MagicMock() mock_hive_table_class.return_value = mock_hive_table mock_sd = MagicMock() @@ -255,63 +281,86 @@ def test_register_table(self, hive_namespace, mock_hive_client): mock_serde = MagicMock() mock_serde_class.return_value = mock_serde mock_field_class.return_value = MagicMock() - + request = RegisterTableRequest( id=["test_db", "test_table"], location=table_path, - properties={"owner": "test_user"} + properties={"owner": "test_user"}, ) response = hive_namespace.register_table(request) - + # Response only includes location assert response.location == table_path - - mock_client_instance.create_table.assert_called_once_with(mock_hive_table) - + + mock_client_instance.create_table.assert_called_once_with( + mock_hive_table + ) + # Verify the table object properties were set assert mock_hive_table.dbName == "test_db" assert mock_hive_table.tableName == "test_table" assert mock_hive_table.tableType == "EXTERNAL_TABLE" assert mock_sd.location == table_path # Verify Lance-specific input/output formats - assert mock_sd.inputFormat == "com.lancedb.lance.mapred.LanceInputFormat" - assert mock_sd.outputFormat == "com.lancedb.lance.mapred.LanceOutputFormat" + assert ( + mock_sd.inputFormat + == "com.lancedb.lance.mapred.LanceInputFormat" + ) + assert ( + mock_sd.outputFormat + == "com.lancedb.lance.mapred.LanceOutputFormat" + ) # Verify SerDe configuration assert mock_sd.serdeInfo == mock_serde - assert mock_serde.serializationLib == "com.lancedb.lance.mapred.LanceSerDe" + assert ( + mock_serde.serializationLib + == "com.lancedb.lance.mapred.LanceSerDe" + ) assert mock_hive_table.parameters["table_type"] == "lance" - assert mock_hive_table.parameters["managed_by"] == "storage" # Default - assert "version" not in mock_hive_table.parameters # Not set for storage-managed - assert "EXTERNAL" not in mock_hive_table.parameters # Should not be present + assert ( + mock_hive_table.parameters["managed_by"] == "storage" + ) # Default + assert ( + "version" not in mock_hive_table.parameters + ) # Not set for storage-managed + assert ( + "EXTERNAL" not in mock_hive_table.parameters + ) # Should not be present assert mock_hive_table.parameters["owner"] == "test_user" - + def test_register_table_impl_managed(self, hive_namespace, mock_hive_client): """Test registering a Lance table with managed_by=impl.""" with tempfile.TemporaryDirectory() as tmpdir: # Create a mock Lance dataset table_path = os.path.join(tmpdir, "test_table") - + # Create sample data - data = pa.table({ - "id": [1, 2, 3], - "name": ["Alice", "Bob", "Charlie"] - }) - - with patch("lance_namespace_impls.hive2.lance.dataset") as mock_dataset_func: + data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) + + with patch( + "lance_namespace_impls.hive2.lance.dataset" + ) as mock_dataset_func: mock_dataset = MagicMock() mock_dataset.schema = data.schema mock_dataset.version = 42 mock_dataset_func.return_value = mock_dataset - + mock_client_instance = MagicMock() mock_hive_client.__enter__.return_value = mock_client_instance - + # Mock all Hive classes - with patch("lance_namespace_impls.hive2.HiveTable") as mock_hive_table_class, \ - patch("lance_namespace_impls.hive2.StorageDescriptor") as mock_sd_class, \ - patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, \ - patch("lance_namespace_impls.hive2.FieldSchema") as mock_field_class: - + with ( + patch( + "lance_namespace_impls.hive2.HiveTable" + ) as mock_hive_table_class, + patch( + "lance_namespace_impls.hive2.StorageDescriptor" + ) as mock_sd_class, + patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, + patch( + "lance_namespace_impls.hive2.FieldSchema" + ) as mock_field_class, + ): mock_hive_table = MagicMock() mock_hive_table_class.return_value = mock_hive_table mock_sd = MagicMock() @@ -319,110 +368,120 @@ def test_register_table_impl_managed(self, hive_namespace, mock_hive_client): mock_serde = MagicMock() mock_serde_class.return_value = mock_serde mock_field_class.return_value = MagicMock() - + request = RegisterTableRequest( id=["test_db", "test_table"], location=table_path, - properties={"owner": "test_user", "managed_by": "impl"} + properties={"owner": "test_user", "managed_by": "impl"}, ) - response = hive_namespace.register_table(request) - + hive_namespace.register_table(request) + # Verify version is set when managed_by is "impl" assert mock_hive_table.parameters["table_type"] == "lance" assert mock_hive_table.parameters["managed_by"] == "impl" - assert mock_hive_table.parameters["version"] == "42" # Version should be set - assert "EXTERNAL" not in mock_hive_table.parameters # Should not be present + assert ( + mock_hive_table.parameters["version"] == "42" + ) # Version should be set + assert ( + "EXTERNAL" not in mock_hive_table.parameters + ) # Should not be present assert mock_hive_table.parameters["owner"] == "test_user" - + def test_table_exists(self, hive_namespace, mock_hive_client): """Test checking if a table exists.""" mock_table = MagicMock() mock_table.parameters = {"table_type": "lance"} - + mock_client_instance = MagicMock() mock_client_instance.get_table.return_value = mock_table mock_hive_client.__enter__.return_value = mock_client_instance - + request = TableExistsRequest(id=["test_db", "test_table"]) hive_namespace.table_exists(request) - + mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - + def test_drop_table_not_supported(self, hive_namespace, mock_hive_client): """Test that drop_table raises NotImplementedError.""" request = DropTableRequest(id=["test_db", "test_table"]) with pytest.raises(NotImplementedError, match="drop_table is not supported"): hive_namespace.drop_table(request) - + def test_deregister_table(self, hive_namespace, mock_hive_client): """Test deregistering a table without deleting data.""" mock_table = MagicMock() mock_table.parameters = {"table_type": "lance"} mock_table.sd.location = "/tmp/test_table" - + mock_client_instance = MagicMock() mock_client_instance.get_table.return_value = mock_table mock_hive_client.__enter__.return_value = mock_client_instance - + request = DeregisterTableRequest(id=["test_db", "test_table"]) response = hive_namespace.deregister_table(request) - + assert response.location == "/tmp/test_table" mock_client_instance.drop_table.assert_called_once_with( "test_db", "test_table", deleteData=False ) - + def test_normalize_identifier(self, hive_namespace): """Test identifier normalization.""" # Single element should default to "default" database - assert hive_namespace._normalize_identifier(["test_table"]) == ("default", "test_table") - + assert hive_namespace._normalize_identifier(["test_table"]) == ( + "default", + "test_table", + ) + # Two elements should be (database, table) - assert hive_namespace._normalize_identifier(["test_db", "test_table"]) == ("test_db", "test_table") - + assert hive_namespace._normalize_identifier(["test_db", "test_table"]) == ( + "test_db", + "test_table", + ) + # More than two elements should raise an error with pytest.raises(ValueError, match="Invalid identifier"): hive_namespace._normalize_identifier(["a", "b", "c"]) - + def test_get_table_location(self, hive_namespace): """Test getting table location.""" location = hive_namespace._get_table_location("test_db", "test_table") assert location == "/tmp/warehouse/test_db.db/test_table" - + def test_root_namespace_operations(self, hive_namespace): """Test root namespace operations.""" # Test namespace_exists for root request = NamespaceExistsRequest(id=[]) hive_namespace.namespace_exists(request) # Should not raise - + # Test describe_namespace for root request = DescribeNamespaceRequest(id=[]) response = hive_namespace.describe_namespace(request) assert response.properties["location"] == "/tmp/warehouse" assert "Root namespace" in response.properties["description"] - + # Test list_tables for root (should be empty) request = ListTablesRequest(id=[]) response = hive_namespace.list_tables(request) assert response.tables == [] - + # Test create_namespace for root (should fail) request = CreateNamespaceRequest(id=[]) with pytest.raises(ValueError, match="Root namespace already exists"): hive_namespace.create_namespace(request) - + # Test drop_namespace for root (should fail) request = DropNamespaceRequest(id=[]) with pytest.raises(ValueError, match="Cannot drop root namespace"): hive_namespace.drop_namespace(request) - + def test_pickle_support(self): """Test that Hive2Namespace can be pickled and unpickled for Ray compatibility.""" import pickle with patch("lance_namespace_impls.hive2.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive2.HiveMetastoreClient"): + with patch("lance_namespace_impls.hive2.HiveMetastoreClientWrapper"): namespace = Hive2Namespace( uri="thrift://localhost:9083", root="/tmp/warehouse", @@ -430,8 +489,8 @@ def test_pickle_support(self): **{ "client.pool-size": "5", "storage.access_key_id": "test-key", - "storage.secret_access_key": "test-secret" - } + "storage.secret_access_key": "test-secret", + }, ) pickled = pickle.dumps(namespace) @@ -449,8 +508,12 @@ def test_pickle_support(self): assert restored._client is None - with patch("lance_namespace_impls.hive2.HiveMetastoreClient") as mock_client: + with patch( + "lance_namespace_impls.hive2.HiveMetastoreClientWrapper" + ) as mock_client: client = restored.client assert client is not None assert restored._client is not None - mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") \ No newline at end of file + mock_client.assert_called_once_with( + "thrift://localhost:9083", "user:group1,group2" + ) diff --git a/python/tests/test_hive2_integration.py b/python/tests/test_hive2_integration.py new file mode 100644 index 0000000..8223855 --- /dev/null +++ b/python/tests/test_hive2_integration.py @@ -0,0 +1,200 @@ +""" +Integration tests for Hive2 Namespace implementation. + +To run these tests, start Hive2 Metastore with: + cd docker/hive2 && docker-compose up -d + +Tests are automatically skipped if Hive2 Metastore is not available. +""" + +import os +import socket +import uuid +import unittest + +import pytest + +from lance_namespace_impls.hive2 import Hive2Namespace +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateNamespaceRequest, + DeregisterTableRequest, + DescribeNamespaceRequest, + DescribeTableRequest, + DropNamespaceRequest, + ListNamespacesRequest, + ListTablesRequest, + NamespaceExistsRequest, + TableExistsRequest, +) + + +HIVE_HOST = os.environ.get("HIVE_HOST", "localhost") +HIVE_PORT = int(os.environ.get("HIVE_PORT", "9083")) +HIVE_URI = f"thrift://{HIVE_HOST}:{HIVE_PORT}" + + +def check_hive_available(): + """Check if Hive Metastore is available.""" + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(2) + result = sock.connect_ex((HIVE_HOST, HIVE_PORT)) + sock.close() + return result == 0 + except Exception: + return False + + +hive_available = check_hive_available() + + +@pytest.mark.integration +@unittest.skipUnless(hive_available, f"Hive2 Metastore is not available at {HIVE_URI}") +class TestHive2NamespaceIntegration(unittest.TestCase): + """Integration tests for Hive2Namespace against a running Hive2 Metastore.""" + + def setUp(self): + """Set up test fixtures.""" + unique_id = uuid.uuid4().hex[:8] + self.test_database = f"test_db_{unique_id}" + + properties = { + "uri": HIVE_URI, + "root": "/tmp/lance", + } + + self.namespace = Hive2Namespace(**properties) + + def tearDown(self): + """Clean up test resources.""" + try: + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_database] + self.namespace.drop_namespace(drop_request) + except Exception: + pass + + if self.namespace: + self.namespace.close() + + def test_list_databases(self): + """Test listing databases at root level.""" + list_request = ListNamespacesRequest() + list_request.id = [] + + response = self.namespace.list_namespaces(list_request) + + # Should return a list of databases (may be empty initially) + self.assertIsNotNone(response.namespaces) + self.assertIsInstance(response.namespaces, list) + + def test_namespace_operations(self): + """Test namespace CRUD operations.""" + # Create namespace (database) + create_request = CreateNamespaceRequest() + create_request.id = [self.test_database] + create_request.properties = {"comment": "Test database for integration tests"} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + # Describe namespace + describe_request = DescribeNamespaceRequest() + describe_request.id = [self.test_database] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + self.assertEqual( + describe_response.properties.get("comment"), + "Test database for integration tests", + ) + + # Check namespace exists + exists_request = NamespaceExistsRequest() + exists_request.id = [self.test_database] + self.namespace.namespace_exists(exists_request) # Should not throw + + # List namespaces (databases) + list_request = ListNamespacesRequest() + list_request.id = [] + list_response = self.namespace.list_namespaces(list_request) + self.assertIn(self.test_database, list_response.namespaces) + + # Drop namespace + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_database] + self.namespace.drop_namespace(drop_request) + + # Verify namespace doesn't exist + with self.assertRaises(ValueError): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_database] + self.namespace.create_namespace(ns_request) + + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + + # Create empty table + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_database, table_name] + create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + + # Describe table + describe_request = DescribeTableRequest() + describe_request.id = [self.test_database, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + + # Check table exists + exists_request = TableExistsRequest() + exists_request.id = [self.test_database, table_name] + self.namespace.table_exists(exists_request) # Should not throw + + # List tables + list_request = ListTablesRequest() + list_request.id = [self.test_database] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + # Deregister table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_database, table_name] + self.namespace.deregister_table(deregister_request) + + # Verify table doesn't exist + with self.assertRaises(ValueError): + self.namespace.table_exists(exists_request) + + def test_create_empty_table_with_location(self): + """Test creating an empty table with a specific location.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_database] + self.namespace.create_namespace(ns_request) + + table_name = "lance_table" + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_database, table_name] + create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" + + response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(response.location) + + # Clean up table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_database, table_name] + self.namespace.deregister_table(deregister_request) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/tests/test_hive3.py b/python/tests/test_hive3.py index b1af11b..b620efe 100644 --- a/python/tests/test_hive3.py +++ b/python/tests/test_hive3.py @@ -1,10 +1,11 @@ """ Tests for Lance Hive3 Namespace implementation. """ + import os import pytest import tempfile -from unittest.mock import Mock, MagicMock, patch +from unittest.mock import MagicMock, patch import pyarrow as pa from lance_namespace_impls.hive3 import Hive3Namespace @@ -27,7 +28,9 @@ def mock_hive_client(): """Create a mock Hive client.""" with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client_class: + with patch( + "lance_namespace_impls.hive3.Hive3MetastoreClientWrapper" + ) as mock_client_class: mock_client = MagicMock() mock_client_class.return_value = mock_client yield mock_client @@ -37,10 +40,7 @@ def mock_hive_client(): def hive_namespace(mock_hive_client): """Create a Hive3Namespace instance with mocked client.""" with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): - namespace = Hive3Namespace( - uri="thrift://localhost:9083", - root="/tmp/warehouse" - ) + namespace = Hive3Namespace(uri="thrift://localhost:9083", root="/tmp/warehouse") namespace._client = mock_hive_client return namespace @@ -51,11 +51,13 @@ class TestHive3Namespace: def test_initialization(self): """Test namespace initialization.""" with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client: + with patch( + "lance_namespace_impls.hive3.Hive3MetastoreClientWrapper" + ) as mock_client: namespace = Hive3Namespace( uri="thrift://localhost:9083", root="/tmp/warehouse", - ugi="user:group1,group2" + ugi="user:group1,group2", ) assert namespace.uri == "thrift://localhost:9083" @@ -65,7 +67,9 @@ def test_initialization(self): mock_client.assert_not_called() _ = namespace.client - mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") + mock_client.assert_called_once_with( + "thrift://localhost:9083", "user:group1,group2" + ) def test_initialization_without_hive_deps(self): """Test that initialization fails gracefully without Hive dependencies.""" @@ -90,7 +94,11 @@ def test_list_namespaces_root(self, hive_namespace, mock_hive_client): def test_list_namespaces_catalog_level(self, hive_namespace, mock_hive_client): """Test listing databases in a catalog.""" mock_client_instance = MagicMock() - mock_client_instance.get_all_databases.return_value = ["default", "test_db", "prod_db"] + mock_client_instance.get_all_databases.return_value = [ + "default", + "test_db", + "prod_db", + ] mock_hive_client.__enter__.return_value = mock_client_instance request = ListNamespacesRequest(id=["hive"]) @@ -138,9 +146,9 @@ def test_create_namespace_database(self, hive_namespace, mock_hive_client): request = CreateNamespaceRequest( id=["hive", "test_db"], - properties={"comment": "Test database", "owner": "test_user"} + properties={"comment": "Test database", "owner": "test_user"}, ) - response = hive_namespace.create_namespace(request) + hive_namespace.create_namespace(request) mock_client_instance.create_database.assert_called_once_with(mock_hive_db) assert mock_hive_db.name == "test_db" @@ -152,9 +160,11 @@ def test_drop_namespace_database(self, hive_namespace, mock_hive_client): mock_hive_client.__enter__.return_value = mock_client_instance request = DropNamespaceRequest(id=["hive", "test_db"]) - response = hive_namespace.drop_namespace(request) + hive_namespace.drop_namespace(request) - mock_client_instance.drop_database.assert_called_once_with("test_db", deleteData=True, cascade=False) + mock_client_instance.drop_database.assert_called_once_with( + "test_db", deleteData=True, cascade=False + ) def test_namespace_exists_database(self, hive_namespace, mock_hive_client): """Test checking if a database namespace exists.""" @@ -178,8 +188,16 @@ def test_list_tables(self, hive_namespace, mock_hive_client): mock_table3.parameters = {"table_type": "lance"} mock_client_instance = MagicMock() - mock_client_instance.get_all_tables.return_value = ["table1", "table2", "table3"] - mock_client_instance.get_table.side_effect = [mock_table1, mock_table2, mock_table3] + mock_client_instance.get_all_tables.return_value = [ + "table1", + "table2", + "table3", + ] + mock_client_instance.get_table.side_effect = [ + mock_table1, + mock_table2, + mock_table3, + ] mock_hive_client.__enter__.return_value = mock_client_instance request = ListTablesRequest(id=["hive", "test_db"]) @@ -189,7 +207,12 @@ def test_list_tables(self, hive_namespace, mock_hive_client): mock_client_instance.get_all_tables.assert_called_once_with("test_db") def test_describe_table(self, hive_namespace, mock_hive_client): - """Test describing a table with 3-level identifier.""" + """Test describing a table returns location and storage_options only. + + Note: load_detailed_metadata=false is the only supported mode, which means + only location and storage_options are returned. Other fields (version, schema, etc.) + are not populated. + """ mock_table = MagicMock() mock_table.sd.location = "/tmp/warehouse/test_db/test_table" mock_table.parameters = { @@ -205,7 +228,10 @@ def test_describe_table(self, hive_namespace, mock_hive_client): response = hive_namespace.describe_table(request) assert response.location == "/tmp/warehouse/test_db/test_table" - assert response.version == 42 + # Only location and storage_options are returned (load_detailed_metadata=false) + assert ( + response.storage_options == {} + ) # Empty since no storage.* properties configured mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") @@ -214,12 +240,11 @@ def test_register_table(self, hive_namespace, mock_hive_client): with tempfile.TemporaryDirectory() as tmpdir: table_path = os.path.join(tmpdir, "test_table") - data = pa.table({ - "id": [1, 2, 3], - "name": ["Alice", "Bob", "Charlie"] - }) + data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) - with patch("lance_namespace_impls.hive3.lance.dataset") as mock_dataset_func: + with patch( + "lance_namespace_impls.hive3.lance.dataset" + ) as mock_dataset_func: mock_dataset = MagicMock() mock_dataset.schema = data.schema mock_dataset.version = 1 @@ -228,11 +253,18 @@ def test_register_table(self, hive_namespace, mock_hive_client): mock_client_instance = MagicMock() mock_hive_client.__enter__.return_value = mock_client_instance - with patch("lance_namespace_impls.hive3.HiveTable") as mock_hive_table_class, \ - patch("lance_namespace_impls.hive3.StorageDescriptor") as mock_sd_class, \ - patch("lance_namespace_impls.hive3.SerDeInfo") as mock_serde_class, \ - patch("lance_namespace_impls.hive3.FieldSchema") as mock_field_class: - + with ( + patch( + "lance_namespace_impls.hive3.HiveTable" + ) as mock_hive_table_class, + patch( + "lance_namespace_impls.hive3.StorageDescriptor" + ) as mock_sd_class, + patch("lance_namespace_impls.hive3.SerDeInfo") as mock_serde_class, + patch( + "lance_namespace_impls.hive3.FieldSchema" + ) as mock_field_class, + ): mock_hive_table = MagicMock() mock_hive_table_class.return_value = mock_hive_table mock_sd = MagicMock() @@ -244,12 +276,14 @@ def test_register_table(self, hive_namespace, mock_hive_client): request = RegisterTableRequest( id=["hive", "test_db", "test_table"], location=table_path, - properties={"owner": "test_user"} + properties={"owner": "test_user"}, ) response = hive_namespace.register_table(request) assert response.location == table_path - mock_client_instance.create_table.assert_called_once_with(mock_hive_table) + mock_client_instance.create_table.assert_called_once_with( + mock_hive_table + ) assert mock_hive_table.dbName == "test_db" assert mock_hive_table.tableName == "test_table" @@ -295,13 +329,23 @@ def test_deregister_table(self, hive_namespace, mock_hive_client): def test_normalize_identifier(self, hive_namespace): """Test identifier normalization for 3-level hierarchy.""" # Single element defaults to (hive, default, table) - assert hive_namespace._normalize_identifier(["test_table"]) == ("hive", "default", "test_table") + assert hive_namespace._normalize_identifier(["test_table"]) == ( + "hive", + "default", + "test_table", + ) # Two elements defaults to (hive, database, table) - assert hive_namespace._normalize_identifier(["test_db", "test_table"]) == ("hive", "test_db", "test_table") + assert hive_namespace._normalize_identifier(["test_db", "test_table"]) == ( + "hive", + "test_db", + "test_table", + ) # Three elements is (catalog, database, table) - assert hive_namespace._normalize_identifier(["my_cat", "test_db", "test_table"]) == ("my_cat", "test_db", "test_table") + assert hive_namespace._normalize_identifier( + ["my_cat", "test_db", "test_table"] + ) == ("my_cat", "test_db", "test_table") # More than three elements should raise an error with pytest.raises(ValueError, match="Invalid identifier"): @@ -343,7 +387,7 @@ def test_pickle_support(self): import pickle with patch("lance_namespace_impls.hive3.HIVE_AVAILABLE", True): - with patch("lance_namespace_impls.hive3.Hive3MetastoreClient"): + with patch("lance_namespace_impls.hive3.Hive3MetastoreClientWrapper"): namespace = Hive3Namespace( uri="thrift://localhost:9083", root="/tmp/warehouse", @@ -351,8 +395,8 @@ def test_pickle_support(self): **{ "client.pool-size": "5", "storage.access_key_id": "test-key", - "storage.secret_access_key": "test-secret" - } + "storage.secret_access_key": "test-secret", + }, ) pickled = pickle.dumps(namespace) @@ -369,7 +413,11 @@ def test_pickle_support(self): assert restored._client is None - with patch("lance_namespace_impls.hive3.Hive3MetastoreClient") as mock_client: + with patch( + "lance_namespace_impls.hive3.Hive3MetastoreClientWrapper" + ) as mock_client: client = restored.client assert client is not None - mock_client.assert_called_once_with("thrift://localhost:9083", "user:group1,group2") + mock_client.assert_called_once_with( + "thrift://localhost:9083", "user:group1,group2" + ) diff --git a/python/tests/test_hive3_integration.py b/python/tests/test_hive3_integration.py new file mode 100644 index 0000000..552d677 --- /dev/null +++ b/python/tests/test_hive3_integration.py @@ -0,0 +1,214 @@ +""" +Integration tests for Hive3 Namespace implementation. + +To run these tests, start Hive3 Metastore with: + cd docker/hive3 && docker-compose up -d + +Tests are automatically skipped if Hive3 Metastore is not available. +""" + +import os +import socket +import uuid +import unittest + +import pytest + +from lance_namespace_impls.hive3 import Hive3Namespace +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateNamespaceRequest, + DeregisterTableRequest, + DescribeNamespaceRequest, + DescribeTableRequest, + DropNamespaceRequest, + ListNamespacesRequest, + ListTablesRequest, + NamespaceExistsRequest, + TableExistsRequest, +) + + +HIVE_HOST = os.environ.get("HIVE3_HOST", "localhost") +HIVE_PORT = int(os.environ.get("HIVE3_PORT", "9084")) +HIVE_URI = f"thrift://{HIVE_HOST}:{HIVE_PORT}" +DEFAULT_CATALOG = "hive" + + +def check_hive_available(): + """Check if Hive Metastore is available.""" + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.settimeout(2) + result = sock.connect_ex((HIVE_HOST, HIVE_PORT)) + sock.close() + return result == 0 + except Exception: + return False + + +hive_available = check_hive_available() + + +@pytest.mark.integration +@unittest.skipUnless(hive_available, f"Hive3 Metastore is not available at {HIVE_URI}") +class TestHive3NamespaceIntegration(unittest.TestCase): + """Integration tests for Hive3Namespace against a running Hive3 Metastore.""" + + def setUp(self): + """Set up test fixtures.""" + unique_id = uuid.uuid4().hex[:8] + self.test_catalog = DEFAULT_CATALOG + self.test_database = f"test_db_{unique_id}" + + properties = { + "uri": HIVE_URI, + "root": "/tmp/lance", + } + + self.namespace = Hive3Namespace(**properties) + + def tearDown(self): + """Clean up test resources.""" + try: + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_catalog, self.test_database] + self.namespace.drop_namespace(drop_request) + except Exception: + pass + + if self.namespace: + self.namespace.close() + + def test_list_catalogs(self): + """Test listing catalogs at root level.""" + list_request = ListNamespacesRequest() + list_request.id = [] + + response = self.namespace.list_namespaces(list_request) + + # Should return a list of catalogs + self.assertIsNotNone(response.namespaces) + self.assertIsInstance(response.namespaces, list) + self.assertIn(DEFAULT_CATALOG, response.namespaces) + + def test_list_databases(self): + """Test listing databases at catalog level.""" + list_request = ListNamespacesRequest() + list_request.id = [self.test_catalog] + + response = self.namespace.list_namespaces(list_request) + + # Should return a list of databases (may be empty initially) + self.assertIsNotNone(response.namespaces) + self.assertIsInstance(response.namespaces, list) + + def test_namespace_operations(self): + """Test namespace CRUD operations.""" + # Create namespace (database) + create_request = CreateNamespaceRequest() + create_request.id = [self.test_catalog, self.test_database] + create_request.properties = {"comment": "Test database for integration tests"} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + # Describe namespace + describe_request = DescribeNamespaceRequest() + describe_request.id = [self.test_catalog, self.test_database] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + self.assertEqual( + describe_response.properties.get("comment"), + "Test database for integration tests", + ) + + # Check namespace exists + exists_request = NamespaceExistsRequest() + exists_request.id = [self.test_catalog, self.test_database] + self.namespace.namespace_exists(exists_request) # Should not throw + + # List namespaces (databases) + list_request = ListNamespacesRequest() + list_request.id = [self.test_catalog] + list_response = self.namespace.list_namespaces(list_request) + self.assertIn(self.test_database, list_response.namespaces) + + # Drop namespace + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_catalog, self.test_database] + self.namespace.drop_namespace(drop_request) + + # Verify namespace doesn't exist + with self.assertRaises(ValueError): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_catalog, self.test_database] + self.namespace.create_namespace(ns_request) + + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + + # Create empty table + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_catalog, self.test_database, table_name] + create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + + # Describe table + describe_request = DescribeTableRequest() + describe_request.id = [self.test_catalog, self.test_database, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + + # Check table exists + exists_request = TableExistsRequest() + exists_request.id = [self.test_catalog, self.test_database, table_name] + self.namespace.table_exists(exists_request) # Should not throw + + # List tables + list_request = ListTablesRequest() + list_request.id = [self.test_catalog, self.test_database] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + # Deregister table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_catalog, self.test_database, table_name] + self.namespace.deregister_table(deregister_request) + + # Verify table doesn't exist + with self.assertRaises(ValueError): + self.namespace.table_exists(exists_request) + + def test_create_empty_table_with_location(self): + """Test creating an empty table with a specific location.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_catalog, self.test_database] + self.namespace.create_namespace(ns_request) + + table_name = "lance_table" + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_catalog, self.test_database, table_name] + create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" + + response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(response.location) + + # Clean up table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_catalog, self.test_database, table_name] + self.namespace.deregister_table(deregister_request) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/tests/test_namespace.py b/python/tests/test_namespace.py index 4c21999..c502e34 100644 --- a/python/tests/test_namespace.py +++ b/python/tests/test_namespace.py @@ -4,7 +4,6 @@ class MockNamespace(LanceNamespace): - def __init__(self, **kwargs): self.properties = kwargs @@ -12,8 +11,9 @@ def namespace_id(self) -> str: """Return a mock namespace ID.""" return "MockNamespace { }" + def test_connect_with_short_name_rest(): - with patch('lance_namespace.importlib.import_module') as mock_import: + with patch("lance_namespace.importlib.import_module") as mock_import: mock_module = Mock() mock_module.RestNamespace = MockNamespace mock_import.return_value = mock_module @@ -25,7 +25,7 @@ def test_connect_with_short_name_rest(): def test_connect_with_full_class_path(): - with patch('lance_namespace.importlib.import_module') as mock_import: + with patch("lance_namespace.importlib.import_module") as mock_import: mock_module = Mock() mock_module.CustomNamespace = MockNamespace mock_import.return_value = mock_module @@ -37,7 +37,7 @@ def test_connect_with_full_class_path(): def test_connect_invalid_implementation(): - with patch('lance_namespace.importlib.import_module') as mock_import: + with patch("lance_namespace.importlib.import_module") as mock_import: mock_import.side_effect = ImportError("Module not found") with pytest.raises(ValueError) as exc_info: @@ -47,7 +47,7 @@ def test_connect_invalid_implementation(): def test_connect_non_namespace_class(): - with patch('lance_namespace.importlib.import_module') as mock_import: + with patch("lance_namespace.importlib.import_module") as mock_import: mock_module = Mock() mock_module.NotANamespace = str mock_import.return_value = mock_module @@ -75,4 +75,4 @@ def test_default_methods_raise_unsupported(): ns.describe_namespace(DescribeNamespaceRequest()) with pytest.raises(UnsupportedOperationError): - ns.create_namespace(CreateNamespaceRequest(id=["test"])) \ No newline at end of file + ns.create_namespace(CreateNamespaceRequest(id=["test"])) diff --git a/python/tests/test_schema.py b/python/tests/test_schema.py index 3ebd100..13a9155 100644 --- a/python/tests/test_schema.py +++ b/python/tests/test_schema.py @@ -1,6 +1,7 @@ """ Tests for schema conversion utilities. """ + import pytest import pyarrow as pa @@ -17,90 +18,149 @@ class TestJsonArrowToPyArrow: """Test JSON Arrow to PyArrow conversions.""" - + def test_convert_basic_types(self): """Test conversion of basic Arrow types.""" # Test null - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='null')) == pa.null() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="null")) + == pa.null() + ) + # Test boolean - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='bool')) == pa.bool_() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='boolean')) == pa.bool_() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="bool")) + == pa.bool_() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="boolean")) + == pa.bool_() + ) + # Test integers - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='int8')) == pa.int8() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='uint8')) == pa.uint8() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='int16')) == pa.int16() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='uint16')) == pa.uint16() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='int32')) == pa.int32() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='uint32')) == pa.uint32() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='int64')) == pa.int64() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='uint64')) == pa.uint64() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="int8")) + == pa.int8() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="uint8")) + == pa.uint8() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="int16")) + == pa.int16() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="uint16")) + == pa.uint16() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="int32")) + == pa.int32() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="uint32")) + == pa.uint32() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="int64")) + == pa.int64() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="uint64")) + == pa.uint64() + ) + # Test floats - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='float32')) == pa.float32() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='float64')) == pa.float64() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="float32")) + == pa.float32() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="float64")) + == pa.float64() + ) + # Test strings and binary - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='utf8')) == pa.utf8() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='binary')) == pa.binary() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="utf8")) + == pa.utf8() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="binary")) + == pa.binary() + ) + # Test dates - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='date32')) == pa.date32() - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='date64')) == pa.date64() - + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="date32")) + == pa.date32() + ) + assert ( + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="date64")) + == pa.date64() + ) + def test_convert_timestamp_types(self): """Test conversion of timestamp types.""" # Without timezone - assert convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='timestamp')) == pa.timestamp('us') - + assert convert_json_arrow_type_to_pyarrow( + JsonArrowDataType(type="timestamp") + ) == pa.timestamp("us") + # With timezone assert convert_json_arrow_type_to_pyarrow( - JsonArrowDataType(type='timestamp[tz=UTC]') - ) == pa.timestamp('us', tz='UTC') - + JsonArrowDataType(type="timestamp[tz=UTC]") + ) == pa.timestamp("us", tz="UTC") + assert convert_json_arrow_type_to_pyarrow( - JsonArrowDataType(type='timestamp[tz=America/New_York]') - ) == pa.timestamp('us', tz='America/New_York') - + JsonArrowDataType(type="timestamp[tz=America/New_York]") + ) == pa.timestamp("us", tz="America/New_York") + def test_convert_decimal_types(self): """Test conversion of decimal types.""" # With precision and scale assert convert_json_arrow_type_to_pyarrow( - JsonArrowDataType(type='decimal(10, 2)') + JsonArrowDataType(type="decimal(10, 2)") ) == pa.decimal128(10, 2) - + assert convert_json_arrow_type_to_pyarrow( - JsonArrowDataType(type='decimal(38,10)') + JsonArrowDataType(type="decimal(38,10)") ) == pa.decimal128(38, 10) - + # Default precision/scale assert convert_json_arrow_type_to_pyarrow( - JsonArrowDataType(type='decimal') + JsonArrowDataType(type="decimal") ) == pa.decimal128(38, 10) - + def test_convert_unsupported_type(self): """Test that unsupported types raise an error.""" with pytest.raises(ValueError, match="Unsupported Arrow type: unknown_type"): - convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type='unknown_type')) - + convert_json_arrow_type_to_pyarrow(JsonArrowDataType(type="unknown_type")) + def test_convert_json_arrow_schema(self): """Test conversion of complete JSON Arrow schema.""" json_schema = JsonArrowSchema( fields=[ - JsonArrowField(name='id', type=JsonArrowDataType(type='int64'), nullable=False), - JsonArrowField(name='name', type=JsonArrowDataType(type='utf8'), nullable=True), - JsonArrowField(name='score', type=JsonArrowDataType(type='float64'), nullable=True), + JsonArrowField( + name="id", type=JsonArrowDataType(type="int64"), nullable=False + ), + JsonArrowField( + name="name", type=JsonArrowDataType(type="utf8"), nullable=True + ), + JsonArrowField( + name="score", type=JsonArrowDataType(type="float64"), nullable=True + ), ], - metadata={'created_by': 'test'} + metadata={"created_by": "test"}, ) - + pyarrow_schema = convert_json_arrow_schema_to_pyarrow(json_schema) - + assert len(pyarrow_schema) == 3 - assert pyarrow_schema.field('id').type == pa.int64() - assert pyarrow_schema.field('id').nullable == False - assert pyarrow_schema.field('name').type == pa.utf8() - assert pyarrow_schema.field('name').nullable == True - assert pyarrow_schema.field('score').type == pa.float64() - assert pyarrow_schema.metadata == {b'created_by': b'test'} \ No newline at end of file + assert pyarrow_schema.field("id").type == pa.int64() + assert not pyarrow_schema.field("id").nullable + assert pyarrow_schema.field("name").type == pa.utf8() + assert pyarrow_schema.field("name").nullable + assert pyarrow_schema.field("score").type == pa.float64() + assert pyarrow_schema.metadata == {b"created_by": b"test"} diff --git a/python/uv.lock b/python/uv.lock index 7a79178..cca2d01 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -231,6 +231,7 @@ all = [ dev = [ { name = "pytest" }, { name = "pytest-cov" }, + { name = "ruff" }, ] glue = [ { name = "boto3" }, @@ -259,12 +260,13 @@ requires-dist = [ { name = "pylance", specifier = ">=0.26.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.0.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=4.0.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.4.0" }, { name = "thrift", marker = "extra == 'all'", specifier = ">=0.13.0" }, { name = "thrift", marker = "extra == 'hive2'", specifier = ">=0.13.0" }, { name = "thrift", marker = "extra == 'hive3'", specifier = ">=0.13.0" }, { name = "typing-extensions", specifier = ">=4.5.0" }, ] -provides-extras = ["glue", "hive2", "hive3", "unity", "polaris", "all", "dev"] +provides-extras = ["glue", "hive2", "hive3", "iceberg", "polaris", "unity", "all", "dev"] [[package]] name = "lance-namespace-urllib3-client" @@ -708,6 +710,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "ruff" +version = "0.14.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, + { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, + { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, + { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, + { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, + { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, + { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, + { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, + { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, + { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, +] + [[package]] name = "s3transfer" version = "0.16.0" From e9872890418f5b59417dc94412d2ae6553d756fd Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 21:45:00 -0800 Subject: [PATCH 06/20] remove metastore_db --- .gitignore | 5 +++- .../README_DO_NOT_TOUCH_FILES.txt | 9 ------- .../lance-namespace-hive3/metastore_db/db.lck | Bin 38 -> 0 bytes .../metastore_db/dbex.lck | Bin 4 -> 0 bytes .../log/README_DO_NOT_TOUCH_FILES.txt | 8 ------ .../metastore_db/log/log.ctrl | Bin 48 -> 0 bytes .../metastore_db/log/log1.dat | Bin 1048576 -> 0 bytes .../metastore_db/log/logmirror.ctrl | Bin 48 -> 0 bytes .../seg0/README_DO_NOT_TOUCH_FILES.txt | 8 ------ .../metastore_db/seg0/c10.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c101.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c111.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c121.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c130.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c141.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c150.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c161.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c171.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c180.dat | Bin 40960 -> 0 bytes .../metastore_db/seg0/c191.dat | Bin 16384 -> 0 bytes .../metastore_db/seg0/c1a1.dat | Bin 16384 -> 0 bytes .../metastore_db/seg0/c1b1.dat | Bin 16384 -> 0 bytes .../metastore_db/seg0/c1c0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c1d1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c1e0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c1f1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c20.dat | Bin 28672 -> 0 bytes .../metastore_db/seg0/c200.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c211.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c221.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c230.dat | Bin 245760 -> 0 bytes .../metastore_db/seg0/c241.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c251.dat | Bin 16384 -> 0 bytes .../metastore_db/seg0/c260.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c271.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c281.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c290.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2a1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2b1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2c1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2d0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2e1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c2f0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c300.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c31.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c311.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c321.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c331.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c340.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c351.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c361.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c371.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c380.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c391.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3a1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3b1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3c0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3d1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3e1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c3f1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c400.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c41.dat | Bin 16384 -> 0 bytes .../metastore_db/seg0/c411.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c421.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c430.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c441.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c451.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c461.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c470.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c481.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c51.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c60.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c71.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c81.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/c90.dat | Bin 24576 -> 0 bytes .../metastore_db/seg0/ca1.dat | Bin 28672 -> 0 bytes .../metastore_db/seg0/cb1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/cc0.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/cd1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/ce1.dat | Bin 8192 -> 0 bytes .../metastore_db/seg0/cf0.dat | Bin 8192 -> 0 bytes .../metastore_db/service.properties | 23 ------------------ 82 files changed, 4 insertions(+), 49 deletions(-) delete mode 100644 java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt delete mode 100644 java/lance-namespace-hive3/metastore_db/db.lck delete mode 100644 java/lance-namespace-hive3/metastore_db/dbex.lck delete mode 100644 java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt delete mode 100644 java/lance-namespace-hive3/metastore_db/log/log.ctrl delete mode 100644 java/lance-namespace-hive3/metastore_db/log/log1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c10.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c101.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c111.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c121.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c130.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c141.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c150.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c161.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c171.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c180.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c191.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1c0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1d1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c20.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c200.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c211.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c221.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c230.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c241.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c251.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c260.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c271.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c281.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c290.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2c1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c300.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c31.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c311.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c321.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c331.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c340.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c351.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c361.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c371.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c380.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c391.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3b1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3c0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3d1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3e1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c400.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c41.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c411.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c421.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c430.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c441.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c451.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c461.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c470.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c481.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c51.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c60.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c71.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c81.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/c90.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/ca1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cb1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cc0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cd1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/ce1.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/seg0/cf0.dat delete mode 100644 java/lance-namespace-hive3/metastore_db/service.properties diff --git a/.gitignore b/.gitignore index f01b926..929f143 100644 --- a/.gitignore +++ b/.gitignore @@ -117,4 +117,7 @@ env.bak/ venv.bak/ # Docs -docs/site \ No newline at end of file +docs/site + +# Hive metastore +metastore_db/ \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt deleted file mode 100644 index a4bc145..0000000 --- a/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt +++ /dev/null @@ -1,9 +0,0 @@ - -# ************************************************************************* -# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** -# *** FILES IN THIS DIRECTORY AND SUBDIRECTORIES CONSTITUTE A DERBY *** -# *** DATABASE, WHICH INCLUDES THE DATA (USER AND SYSTEM) AND THE *** -# *** FILES NECESSARY FOR DATABASE RECOVERY. *** -# *** EDITING, ADDING, OR DELETING ANY OF THESE FILES MAY CAUSE DATA *** -# *** CORRUPTION AND LEAVE THE DATABASE IN A NON-RECOVERABLE STATE. *** -# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/db.lck b/java/lance-namespace-hive3/metastore_db/db.lck deleted file mode 100644 index d3874c99cbea4a587c86842f86d85c6c39c1b078..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38 pcmZQjNwhFDOExe_)ip4*Owu(sN&&LclFW1sK)~F@EYZx+0sySw2<`v? diff --git a/java/lance-namespace-hive3/metastore_db/dbex.lck b/java/lance-namespace-hive3/metastore_db/dbex.lck deleted file mode 100644 index 720d64f4baafc33efdf971f02084aca5f25b34a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmZQzU|<9Q00jU7 diff --git a/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt deleted file mode 100644 index 56df292..0000000 --- a/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt +++ /dev/null @@ -1,8 +0,0 @@ - -# ************************************************************************* -# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** -# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE RECOVERY *** -# *** SYSTEM. EDITING, ADDING, OR DELETING FILES IN THIS DIRECTORY *** -# *** WILL CAUSE THE DERBY RECOVERY SYSTEM TO FAIL, LEADING TO *** -# *** NON-RECOVERABLE CORRUPT DATABASES. *** -# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/log/log.ctrl b/java/lance-namespace-hive3/metastore_db/log/log.ctrl deleted file mode 100644 index c23d2871bf135b162dee70f3081b449e95be1c11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 hcmZQzU}#`qVBiE|7~ldj_!y+0J%$Ou=vNL~)B#Co1d9Lw diff --git a/java/lance-namespace-hive3/metastore_db/log/log1.dat b/java/lance-namespace-hive3/metastore_db/log/log1.dat deleted file mode 100644 index 81a129c1d074d1e8f1c665393e5962cb8436da0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1048576 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 zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r O3>YwAz<>b*>wy4$E;Nz= diff --git a/java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl b/java/lance-namespace-hive3/metastore_db/log/logmirror.ctrl deleted file mode 100644 index c23d2871bf135b162dee70f3081b449e95be1c11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 hcmZQzU}#`qVBiE|7~ldj_!y+0J%$Ou=vNL~)B#Co1d9Lw diff --git a/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt deleted file mode 100644 index 2bdad06..0000000 --- a/java/lance-namespace-hive3/metastore_db/seg0/README_DO_NOT_TOUCH_FILES.txt +++ /dev/null @@ -1,8 +0,0 @@ - -# ************************************************************************* -# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** -# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE TO STORE *** -# *** USER AND SYSTEM DATA. EDITING, ADDING, OR DELETING FILES IN THIS *** -# *** DIRECTORY WILL CORRUPT THE ASSOCIATED DERBY DATABASE AND MAKE *** -# *** IT NON-RECOVERABLE. *** -# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c10.dat b/java/lance-namespace-hive3/metastore_db/seg0/c10.dat deleted file mode 100644 index 3e1aec63554501fdcd0defe3f4e6eb6fbba30fa9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI1J4*vW5XWbakatLmsPWw?2nH3jkQBx{Bs}Z6TF11cY3B{A=?GJ{ zE+K)j5xrF0-rGNLUq*`v5CI}U1c(3;AOb{y2oM1xKm>@u-v}@b3OL1P0l$938xExa VPoCX_U9`_Uy8x?x)%U|H{|2MJW19c~ diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c101.dat b/java/lance-namespace-hive3/metastore_db/seg0/c101.dat deleted file mode 100644 index 1118178122878d154f3dc957aedb0924bf7933a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI0F%H5o3`Ok@ZAT_%Hb$73I0Itl2+V-Qf>;7 z7b%YO?ZnF4Vp)lZ+AK!mZ0c-mLOj;Yf0m;mf80(jvap$pbV8C^aoc|#t>urSThE`0 z?s7u^YKsn|B0jHXUCn%3)7U@&0uX=z1Rwwb2tWV=5P$##{*l1`uvS^x%fbgcabEWJ z)(~$7(#%>0JISj?K&w}s3jchSfnL0-;p(FGQ1k*OGAr}%PO+xMsT5cs009U<00Izz Y00bZa0SG_<0ucC}z*y!!dGqL=Uo0^$Z~y=R diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c111.dat b/java/lance-namespace-hive3/metastore_db/seg0/c111.dat deleted file mode 100644 index 71b1f8d3f96f1adb7b0cd89180dd4c7c8814d408..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$D-Oay5P;#?Hfby21~@Dj5)up-AQ%j1KmrL4gX9F{!tn_B#13R*- z^zE)8Ur!{d{xaA}R{RKPToq4+?|dVDb9PbF_SsnHy!=ciGWW5EjfuopA7DZN0R#|0 a009ILKmY**5I_KdUj;_8a7Qnv;rIoJ;V!rU diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c121.dat b/java/lance-namespace-hive3/metastore_db/seg0/c121.dat deleted file mode 100644 index fbf18b9c97f9d8c1268253438a612ab37daf5f8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$Jrcn{6u|MfDUy_qK&7NoIfGHC96^m4okporx`EaOoI>LQbZ)@gugr=tYV+Tj z?8ke%d6Qq4m8FOneQe8IpSwQoVm^)O{1I9${Bb$f%v_&Rq!l+AEw1aYt+D)JaBKTh z$-7*jd)2}8lOlfKOYdry>z5b{1Q0*~0R#|0009ILKmY**{!w7NUm02Gm&G6K%*~3o zZ;knSA}{pHU?XL95zsiRPR0LxBRzBWQPT-od-Y(;k7ODmcO7lv>=XhF2q1s}0tg_0 Y00IagfB*srAn?1uP-cGfWj8rK0W4ZBr2qf` diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c130.dat b/java/lance-namespace-hive3/metastore_db/seg0/c130.dat deleted file mode 100644 index 7b2a6548baada97b880355f2e256c0229b1eeec6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$F%E(-6oBDZLa+k^n~90Daq|G4fw&s3fhKNVz!P`@@8c!hoSgMhcuFb`PA29r zp_KQUKKgA%wj$#6ZdwxhEcE@(^8J{O?_G<+A759RsoQK}lX5NY?d6;2)vv2)t?n~t z7md4x$g{}6x}m1u4`c`-fB*srAb^O2lK%zz8 zQZDwL6DO~;Wg{YLSJ4s|Qy1e9>T%Bc&$2brABS_RtnA7~x?z&q;x_);T9-eK9zFk5 z^e&g^-|eQuXc0fJ7Tucpu9jnf00IagfB*srAbfc-x z7T2XnQ>5oyU(=m>GK3I7009ILKmY**5I_I{1Q7Tyfy?!%vbQ^h_kH4LgST6Te3VEt w+dtJ?8`koPpUPT?zPAZx2q1s}0tg_000IagfB*srAn;p(mCUPx=lg8(0!6?R4FCWD diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c161.dat b/java/lance-namespace-hive3/metastore_db/seg0/c161.dat deleted file mode 100644 index 90960e6d4a00549e71d007bcbb2ef09b92b2e39c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$yA8rH5P;!xiXCKFiCVpQdx}N2skz;`X0tg_000IagfB*srAb`L>3Y^Y+BOCp)_=BCfS@HI* zvEDA^g&r9krK}GEI%oA$@ju_l(A<62EJM{EJ=peBS%iu`EwGKVt4|OSKmY**5I_I{ X1Q0*~0R#|0;0J+;to-h3cbmTed?PMZ diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c171.dat b/java/lance-namespace-hive3/metastore_db/seg0/c171.dat deleted file mode 100644 index 55d40959a493d5ee3bf7cd04992bfc655896f7ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 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 R5I8^edt$hmXW#y{{|7={7a;%u diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c191.dat b/java/lance-namespace-hive3/metastore_db/seg0/c191.dat deleted file mode 100644 index 5e31e3bed2c2e5d2b5cdc59498a27d8fabc5ae3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI2U5F%C703VmS=C=Ny|dpR*(94yHZe}pyOZ6W-6T5I)pvR;Q{7dms@~n%T`k=t z`=C#vSr9=YevrqAFY23w1bh=geG)}b5CVb^K|}vlw z)ZAP3yXTyH?#DURxDTK}U;dP3S(W8%F=?Nzqw9Z)s5OGI773I2OmXZ$hGPgi( zf!qSQ1#%1I7RW7-TOhYUZh_naxdn0y{O?=f2Z%_C7x4K+mFWF*|Co#aZ{bO5*4s6Z>I>w}u8 zC!o<_I7PJ3&_}efLWpfI5Ke!%BX$+0XrQT&;minOMngMtyrFLe)0#KIHO z6jH^CJ|xkqFQRDI7tV0oo7lHl!|Gl!G)e<2*qt>_p^mmbCK+!(@NCf=1%d`%sa0s= zfIesyEwZu#O(`bU^eM?$g}$&Ii@k8xd5R_u>XQxz^KQNv+IOi2;a;r*I;LI3uJ)HgHuRNvqNr>55@L zx~2qc;(2`vE!tyBIO;BF*uo3?ps_fih^7>2`4zmVPoZs*#fbviV#y&`Cka`_NAw}& zQ{7CTYU88&B=RXHW%$$qY;EbYPT&}`7M!ZP8zsjgb^xP_ElZzBPL)Dja4N&VR#%@% z!#HNndzE2g%ht!xIF2#%3f8dI+cSlHN>SJwj5@Z&o+*nyWi*x!?RiCRf!qSR7O1{Q z@10S-jn4p;5AZ1}-=_D_sKn?|c?veYg#Ha*m%oWEDzBqUWdl3(+WO}lGnc-Am#DnR z*TuiUq4FK{sr>b~8hSAaixww*& z704uVSSEj5Ac?Vzhj^Rk{jWqJfxc`PiiY}`d$#lFONj9%j&X(<+O}JCh9ECETbrv=#t)EEN({Ilw+BoE47q7 zLMD1qN;N1_%4$k3ArrMIr9@>)X{O{CGSMnf+YW@dC6@hgH6_WANqYz<6LZpmOrc^* zI{5T!7db@IBO56x2R$YoVIzkUXme=;$!w)0A2OLrYnF3FKgEeH+a_n{k!D)8nv#Ub zq^a5G45UBKrU=VvIfzWs<9IBw-wY`kXO5MY{4p&%k;zv6IA+iLqnVYcNQ>_2H&1h7 z&iG@hob{{>MjBj2#Lh5DLfEM*5p8)HIgJNGDeCa7UK|R06gbgt?0c?btHq%W-IG4CGS~#;08n0*zG+xn+6+EU-Q@Zl#j%guTZlGR$7^^tD58jM) zQ=XKsjmPzQYQ;@bT+#t2qiR<1gg!}~cj&A`y82ca-tdB+f*Clc4^u-*2}oy~7MDeu zi6`}G2e6tJi*nf zvvFB|y-y36_u*4S{cA33ceylw!O_0)6puozRhLxXWUwHxxV-TlZ)>%r??}pA@c%fq-=l0HR}C~d}rai^oxGfi!#e_hh;9T V$(aAAoC~1*!d(1s{rKHK{0C_JjD`RJ diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1a1.dat deleted file mode 100644 index cbe66c52ac7e3472a5d13d35344650aa6025d2ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI3OK%-D6vxlZ+-uK$CIuRvr94X7l!kg<9uHI^t1h9ug2Zl~e1Vd6H{=U|B32+a z*|X^yv8dE9kdIKYN9qCz!5P~(4{nk}mqfl&PA2xx9?yU58UIgjVFv&_{OLaf9hr{D z!=nCp86N*_KmRH|^Ur%&b02>~fYk-$;mPsub3b34R{PyX+?n!Yed&VhzvHh!n3MRY zwZ$@h&hWt*wXWDH;1qBQI0c*nP64NYQ@|-!zlYu~ z_cs0HXHkE$6b1}!v=6%w9%cegJ+jS?jJ^lAy#rI~{cLOdGxy1WkKij?^FWsX_`l-8 zB1hoE*2e*?!?nEYgb+$>im0eI^SEg@MOVp9EEFP7Who;C0kFwo(*V11AE$s*z$xGq za0)mDoB~b(r+`zyDc}@v3S4{zet{40BJXI=j|U(Ab>*iM{{KGQ#NyAFggC?h1LJ7_ zzddgMZPVb;bRU`iBM*-*pZmRs7b2|$`gg*^`y4{U$D$RYpgcccfsx^}EE7Uf{Rb;B zHhdoCm^`5P;S?r@SFub*6cgk3Mldye5fzxTp!(+_%naYAWh!#2|G^CAnvdcP$5T*z z$Y90rDr=R9YGVBU7*-8mM^cH5)( z$xq=0!)L0fg`{}QYh5;co+Y)&DV{M{GklRXwNMn#$MB-z>ompjW9I7I9G1TVFB!h8 z1dfN|*$7_Ne9|PizN8}h59aWS=2MZRI3F^C_oncwi}OuV{Rb1c zVt83%hA*f1VF<4qUKKds6veYuxN7)DcBzmhalOGRyrKClN~%;SisvJE)9@(AB5?qfFCT-81|K1F47`|xnd8nxV`5ZP3-&VLDbE^O02ySXVuk#ew3-x{p z7$%{0gS4!1!4%Yl3rDbZ&zvD{@rny-MBx~=KG6+CmEjUDs8>cfgRM_>gSaa38Hy?K z^EC}uVCyr}AgOUt7SuyJJp7v7()Pd=I0c*nP64NYQ{exk0B3;T66aq-1i%jZW45p3 zj*fSATo?%m|Cb^zalf8W`j4&uFC%ngLQ(zmiS_?wTGi;!ss4k7|1YJKxWA|P zA+!F!R2lkbMe%HI{eM~Jc)bP1hur%AvT2Z)ls_MgtpBf~8pp3Fp3kiRuT+Zptcdd4 zKC}M6YCFs~&(NUdK92I|erWxFU6kmz71ckVTK`{nNrwKG>VG)1{=cak)KgOaJQ!R5---nD z5m8R)@6E0MZ}C}$d+6a>K#Y`u|Q;n2%Ew&n{X2->C?n=Mm-SJ#PJf*GBk!&MAH{fp_)$sI3IvuY$VX za00h9UndE!--23?;S@GC-y{m}S3%9Ua1QU8{;Lk>TS3j|(enTBTYBZY0;hmez$xGq za0*;(1xyxT+5e-TNB_+3>bTa&v$6nuPuH&Zkw5CA$q1a43*en*SRa=&0%zp{{!13% M+5G?D@^9P!0BGrK(EtDd diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1b1.dat deleted file mode 100644 index ae654971565c9fba795a5270251b9a46af8f4c65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI2zmFS59L1k^*R!*`{*`e2Izkd4YA|xava=BbV4FMs9 z(m)v@pyCfe2&F+#q6kHzprSz$qN1cg2+>f&ys>@foX6nhTOguY$Qc`3xN|%%j z6&a;RN(EIJWtEgFYBCBh)|6_f%P4(A2^1PK%7By@dqk8~)^4D&S4Ls&1_^GFQCPb{ ziX|C^wHsu(RYWl}Jw#dIHW`IuRE}}Gh%(@JQ5tv1DEuxe!JQIHFK4}|6w5Odd(pGM z*hSAZ&ZDq~yJQsl64tR#MxifZ19!VAi(ba%u`Z}!zl_3TT~NgV8HLBXpoZf!lme?- zFXxnRx8xx8>{bFU8CyXtbWGV>rJcssqqh1Kd^d= zTHdg_j~ZRK`o7iYtVY!Es?|5GwyD7{RzI=&iq&Om>3ge}tv+itpyDg57p<=2_-NlR zU%PVkhWvjFM@>(A)H|jBl>f&s4IEbj7S8|w>L>h}1)>mzYjDtTd60vC_IA(RhQ%NX}aDCQq-W{=_u?v+vKOI*c$G75c(Yd9pM z(3iN5`(+fHxEnYuqj0s?3M(Q?n{!&nctA$soYopgWE9S6o!~(kg>zb`ct}QJ?dl9i zWfaz~uAnKSuy%D756dX5U0uU58HKg0>&RskTe}UkL=^L<+7OAFN(cU-ci?~HK=wN` uaCXJ&meqsQ^hc{7Sv_r4Q>5t3OD$A-0<9P3_pmW_xQUDh(^bLUeR^QorsGgwRhxSeZerK=R_$3sS&>;9{Cwm(lE17DT= z%L&7~e#|&&;?Fg_>sjs^8XE{e00Izz00bZa0SG_<0uX?}KN2_`w?@`_v-rTyTvWW> zHRjuiywH)sUdnn9&>7WL@ttpEWNuzHRmj@WgPjG;WDzn~r|3|^1{ee&009U<00Izz X00bZa0SG_<0>2TM%F-89r%Uez@u)7| diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1e0.dat deleted file mode 100644 index 761408d3b3483e2cb3bc4d3d46e37c5e92d2a255..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u?@m75J1s8gMx)9XsIY^8GsoOEn*EoqGJIjUU*)|)wt@6|}sAD0WOtjp>!ZW>r~9~a-eZ+^K-&Z<6h zQdnN6BCjSb=Z2ns-%=rk00IagfB*srAb<{9 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c1f1.dat deleted file mode 100644 index 78d701f45559f9fc67104563ad350118d55c794e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 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 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c200.dat b/java/lance-namespace-hive3/metastore_db/seg0/c200.dat deleted file mode 100644 index c3a7808dd76bce2cfa24ab40d4e9e5d87dc76d32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$u?@m75J1s$1i=Lb3s50M%K*%PXb~gO0uod#zy$2W0xUtt2yk3-Nn}DnLxH}d zIQE_8i(i+>PDFysP}eC&nJma vuIq>4T8HfiLRaS1Ri_vsfB*srAb95yH6u_15*-aC4FwGwFa=XE155#DJC2+XkZ936 z$>;moC%?`o8xb+OoLH|juTvHCX-w^BDUI+)cdnV0u0o^}i;Ol`|EsjNzf2yza4NaW z2l{v2%qVFR>T25eEOxaR4g??o0SG_<0uX=z1Rwwb2teQ;2^`K_BWrzG{9s#eYevS+!R9<8rQYf;t#g zG2c#Pxn3FUrKm3gI%oA;@ju_l$Xr9z4yvrXdT`}uvZyld;R@Tco6!(J009ILKmY** W5I_I{1Q0;rCxNLf!~V;?yuASIbS~8Z diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c230.dat b/java/lance-namespace-hive3/metastore_db/seg0/c230.dat deleted file mode 100644 index 624a5e8baa86d23af2fe1d95d9315f64ec0a33a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 245760 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 Lz_B8L^8fz_ikqu^ diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c241.dat b/java/lance-namespace-hive3/metastore_db/seg0/c241.dat deleted file mode 100644 index 743806b6ddfcd62827528081f864037bf8996df6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 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 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c260.dat b/java/lance-namespace-hive3/metastore_db/seg0/c260.dat deleted file mode 100644 index 25f81fde784105363c372eba91f6175388235f63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u@b>R5P;#mn}{nEdX-A+0X&0YhQeq(1ZH$RfG6-+YQ4@Qur682oG3I3^Is;H z&F;-@?&~635pjAyhmUg}=lW#zdQRheIg<3p*NIlvMYU^-I@&zg%Qw$kSS*vh%Fi5J zHSdNZuO#5CmTJJ{onf-wck!@^`wyH wy1wVmRobsK&Sb3DTxM0C2mu5TKmY**5I_I{1Q0*~0R(<5Fp_@J@zR0f6#Y9cqTpT@tH{d|bj(Q4xw3HM?<81yW zJlgjPFMJ!7gNPWtsu9_k*cb+14|6(y)}xdDxLjyur&lI2@SBV_*Y(%Y+rF4RM((NL zT{bbk>&;ApCT?FV+Md~|m1BVb0tg_000IagfB*srAb`L>3S6#7BYXWa|AQUbS^D;^ zzTPb)sU8`eC2I}>dS}g3{y*Qy)RZn8ZR={R_p1F;=CZ15Ynu~^Z!SSZ009ILKmY** W5I_I{1Q0*~fu99(*|@z$K1^TR&n;~L diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c281.dat b/java/lance-namespace-hive3/metastore_db/seg0/c281.dat deleted file mode 100644 index cfed875dfceab65004fe1b91cbefd660cea0ccb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$Ar8VY6oBE^iER>v#vwtWI0HeW&}bmRfk1KsZonnr0Ml>(Y%uf+c^G zy|wRkYxcQ4S&N9#%Z|jw)WtZ2dYsewvmA}|$K_NjOTBWDPS|Aha9w{Lt;e56kDh-j zdY4P|?|L)C=n%iJ7TuZoww7ao00IagfB*srAb{RQS&~GB8)4O?G9~wjOLRU?Q`!GItqmN?d$`hyVfzAbchAM`1#m1bdH?_b diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c290.dat b/java/lance-namespace-hive3/metastore_db/seg0/c290.dat deleted file mode 100644 index a85589e545d81d6ae0a080bcb44ba28d846f9987..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#F$%&k6oBEEAT@}CcmX$E-CXntic1Ia8Y;MX0YT{KvAlqz(81YBpJ`)Dt%HM$ z{0T{u_tK>Kw#r6CjJ9X7zK?ug?n1sC)A2nomGH;uTr;aI+X;)>dbkUdZ=P4TSXTDR zKXY)=xEYGP4yoDKpXqir8A1pkfB*srAbwe_@>s%c3oQ?0Sqw0MUR0tg_000IagfB*srAbd`` MER$^4q<=d<0Mo1*Jpcdz diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2a1.dat deleted file mode 100644 index 8e2ed6afe90b6e9bab82029f98a338a3cf455bf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$yA8rH5P;#cizFp%Kt~A`6*C}eBo?3sBr0eqk?5&tnSv>p0j7Y9ACVIR5-s{I z%49v}E?KxD-)~u`K-V?%Zx)KyfWW diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2b1.dat deleted file mode 100644 index 2a2969247718ad8c76b895d72b43a1f781e3cbd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$p$@_@5P;$9mTZ$e0uBoXg~t&L2Ez*=fdq#^F2VB#I9>*g1jie|tzDOH41y+q zlik|8ZkK&-m5qoPy^0apnAjKwUk`ISf0m<>{?NxX0$OL)Q~p2S$iQ4&HaeHpSnoyqnM`C})($o&5?@_{hyVfzAbbTe~jZ7z9oJ zP1cXQc9;F!Dk~8&`s6LLePa8t^Z78Q^Jmd&;g8FSW)}KnA}znkXmMSCZH?uR!&}## z3f^S{y{itU9~5!>D!r|lZ7MMq2q1s}0tg_000IagfB*sr{G-6`ur{*PFY`axk)5S) z-|F-AM3U;2!B(>JBA{_rp7Q_sMh52WqS2|y#yZAYek>iC7P-BS`ISU`aRGV+5I_I{ a1Q0*~0R#|0009IL_*q~ibGNsBpFLh?bT1nK diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2d0.dat deleted file mode 100644 index 4adc6e4470f86182da42ea94fe6881290c97948a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#F$%&k6oBEEAT<;RZ{Q#zZXTdlP`ZlOP{GX$cmgjaNLOb!2M?gnw6P`D!No!T zl)k3#g}mn5DjN|odOwHtG4Zh(LcN*O`MnxZ`r~V^l~q~ohebVY?!wDA&#PN3qrIxn z9A7kVrXsH@rJ7uUx zg-)XDhvrnL?NR4W=KdOJoJnrdy3Py%1Q0*~0R#|0009ILKmY**ek72|r0jG%7o!J8 Ck`^og diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2e1.dat deleted file mode 100644 index b37b9b254234c4de527ff90f13f4624bfa8f98c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$Ar8VY6oBE^E!ieH0*(X)2E`c&nlm7Q1cyO#0ult0)1YQB;NTSS)~-u820@d* z%U;{}x;6XUDk~8&dKWFSF|jcWz8>au{484|{c$?g%0ll90R#|0 a009ILKmY**5I_Kdp9RJ;cWW<){_zC{d@qgw diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat b/java/lance-namespace-hive3/metastore_db/seg0/c2f0.dat deleted file mode 100644 index d854b4b482d64363d5e58c63e9e4d8e5633ff2ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI%F$%&k6vpu{R%!(Y7eR1yarFS6LEOX}cmNgLynu_2p1{Ssh?j8m2Kr1JTWY&H z$Uo3Dc`wZ)zpbq{lAK-d*6@Ao`(hXJ#h8tsSu2HWr!&i}(rh;@>R9n4Olt0x<(HR3 zzqD7jZgjV}8%v)e75n;{$*v+p2mu5TKmY**5I_I{1Q0*~f&UWNpSDhGJ5zYUj{FyZ z@7M8=FCD)b+mk(a%fpR_-)$f}$Mf(7jh+<3 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c300.dat b/java/lance-namespace-hive3/metastore_db/seg0/c300.dat deleted file mode 100644 index 2053e0105b40818ea4cc1ea3a6c1cb5edb9972df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u?@m75J1s$K*2&3Y>^6y0a$=0qM<`c2CTypbc_HOCr5$_1qBWI zw&I-cEIWQ(WGf<0pQ0sUOvBh5tlrFNe6L!R{y3d!WnET>wrHS-dz*aozWK#6+N=7^ z?5cS;7I_}hvTr!k?^`OQ5I_I{1Q0*~0R#|0009IL_%DIOY3F34ce4NcBt*TpTUtFT zbW>fQxl5hy6k%U-nQPBqdcBAU0R#|0009ILKmY**5I_I{1b#0tkx_Zb>Nq_=05p*m AuK)l5 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c31.dat b/java/lance-namespace-hive3/metastore_db/seg0/c31.dat deleted file mode 100644 index 7ed780bf8a4ce088bb41bbc28d9a2e589f1131f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI1JChql5XW26Y4two3>;uy2F#g<7tic-1`HOj!^YquazM7P3CN(p5h)d;zD>-78rmowQp;M%C_>{u<5xdZwqRXJ(~?TL93)7hP>uht-zl zeY+0J|17SJ>YX1y$2;HPs}C?+LM`kZKUZE?x81#SuRkd3t+u%0!e98-5>_W$?77dn zji7|iE#4D#{1_(8N6OckknF#9J>_XPH(8G66rVuKpp4H1_U-m-G{V_ak^L6>zp1@g)59;!>y${dWeBJtOPvKdcuZ`yno?{+!-^V?I5CUc8CS7a{M5ohiJwoyYvijdi{(_!+#uozL7zq!cci-&Oku@Wv_L zcMH$++{BM5y%&6Wes#{k#a(<_#I&5(_&o>QUA)$Oe5~_5c$4|{^^yrMbOR-p?c;gj zaeVgraH)c)?Sk50@dFSQytN(|?GHg#@U&g8w?6`JlP`SN7+mjuoYD5E3qSGGuqgc> zgU`HBUKEti56DLmK1qa$KFv=c*lZuOAWUOS>Z0I$K$oOenNs+?v9}Ll$*T~LScwix zfwNlp+D%nK#~)o%7<>^wg@}12JdA+Egp?w411~DvEYzGoWMF6lh@U~syipQIBr%_f zPcwxlN5tD**}hIv_U8Z;^FjnE`B~#n*8$CZtl~@vN|;LjyFGY|`AjFc-zuEY(*FeW zxsY_6@nxdekU!l%yv_Xjcz62W9l&MgBM}D}Puw4>{TaeLr9UDHm5}UDMf|%Xc$fJ= zm{ ze^|P-O6sZ}@VmhLqtc~Bdzn$xgC{YeP2y&W;awMl8u&#lDJz^l%#TZ#QarY!l|i9h zjnAr!G+G%9VE%DwP$ZEt35At=C?eO>D4cax4?~z=WrHxw!Z5<^e`OF90dKr(E{$M* z?bH}>laSOy7A`X*h|@6OF^pmU2^(l71s>nrL+D}>;p`;|oji0&t#!c$m>So&j{!F@ zPn{kErpBk6J@|nugCul~EFbPMswR>~Q))Pv8lUYlNFuS=T`Yq~|3Ag=S^xPOoB;mE zbr_M3&jNm}8yr)4^aGWL_ozHLB<EV7<$FoAoB^ z5ozlo>m63Z8nHU0aG&*rw8u=3nch9FVa8#m$5xXmjc$CMbo2|4l$r6*RGxgrcfTWT oaSNlrnc<u1>-;g8#yW>(rWk*+^vw7BlSw$}3J(Y^1U z3f^S{gPTq!4~n>Rwb9nhcC{EA1Q0*~0R#|0009ILKmY**{!!p?+!|Tym-!#;$gVnX z-|F+tMB33SgS}+cML_GSddmOj8yT9bi^jb&o9G;C`MFHBFUo8&#oCjH3os&p00Iag afB*srAbVZcRFqIrAO@g9)UwmeL4+bQhZ0=*mU9p~z@+^}kAM`^)&z^QWS_ zTwrk5&5WWZzOJTS&-_q};XnWa5P$##AOHafKmY;|fB*#kk-+J^H?q~2g%5V(tnBTr zA>T}-nT`yOl2?O(R;xM{{`p3R=IW!JewnqS2RjRx%d*Va%{ER7YatMT00bZa0SG_< X0uX=z1Rwwb2>e7~Dr;YVTTNy!_+>2u diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c331.dat b/java/lance-namespace-hive3/metastore_db/seg0/c331.dat deleted file mode 100644 index 85ee72b31368516c6de9fbe3516e0e3229ea2755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$u?@m75J1s$kdl;)Kt~BQRLp=V5hG9o5*-bqVgfc`3T8;b1Qaj@ob5PrLO`NL z-;y2s&dJHIi)AAsM!Ri^8&fyNL&(Q5oj=Rg2!CA8G_%s4i*&;#qs4XowY8Q%j~_k% zR`e|w=->5WhEWl}uQs}x`K}gYfdB#sAbHq)$ diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c340.dat b/java/lance-namespace-hive3/metastore_db/seg0/c340.dat deleted file mode 100644 index d99b11a3f2dfe2333989898bca9463dfb265ef5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u?@m75J1s$K*mB8Y(Rx*8GwQbEE)>L8i0goSb&C>ozfsN105s4;lv~|p`f8a z-%*^)o#l&P7ukr2(fc{FFxxQKr&zD&G`^Q3Nq>BuX=PPZ`*BfEo4fe(&GY6K%Ve+e zGe=j=o3Y5NNyEOOr`tDFNFjg#0tg_000IagfB*srAn;!Thtt-`TF(^!@3Rnf-cA|o zNuh0Z{lJ{7bZe@y6)$tWym-^CYD5SifB*srAb%c`MXo7z5=i5{uUv--&9MZ&vF5D`EC d0R#|0009ILKmY**5J2E3fuStizH|39egYK>F4O=3 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c361.dat b/java/lance-namespace-hive3/metastore_db/seg0/c361.dat deleted file mode 100644 index b5c8f259d0d1fefc112f60325bfde24724aded2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$u?@m75J1s$kdl;$3Fs)HqM~2|L`_Fa4M=n}luW<|Ou-be0fLqV;B3c{69N(~ z`j&FB@0?h9T~5{_V)U{jaWQo<4xt|Bbp9+xE&Xvh)yh(@T%;W~89iLrUq|Ed$Kk!} zpNih)61|(=%pf|%@2f<2X1=ZDSRjA^0tg_000IagfB*srAn=a@`@_b_O1~`pU?*;t zy?tw_*9&Q;ErXrpWh0<*Rz4N}^NsY)*=JkxqH0?YwihswSy36gj5Z}sK0!nP0R#|0 a009ILKmY**5I_Kd9|T6S@Vl>_%i{&Jf-Z#s diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c371.dat b/java/lance-namespace-hive3/metastore_db/seg0/c371.dat deleted file mode 100644 index ad11f01b25b6bd995142e4d731203e66b5792409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$u?@m75J1s$kdn|b0v)1)ii&~>5H%AZIwU}%qoHI1HedoureFq`0?u|EIUyj? zqHie|`!3EYuZv|XB1SJe5*Je!;}Gg`PUp{J)Y2c9Gp(%k%0)WiA*0Q8{dF|9KaU<= zzbkr|OZ4t~GsCEff36Z;&wO9Wu|NO;1Q0*~0R#|0009ILK;Rz*j;EcGjec49!A{&P zd;8Wiymj?ljvvODX&o?qKH=k{-imE+&uQNLF=_GAyFYfN*B?k-~k{H zkXNBcJOCYU0poF;L}9ZeC1`BjckB6cpXX=$q&xTk013VNZG&~ndRE5#*%+;V9dGBt z7ap!D^KQs4#-cfy&&Gob-nT;Wmmgp34DplCIzG*ZKPjFdz)2#|&z`gWKt@7BKnMr{ zAs_^VfDjM@LO=)z0U;m+{x1Tb4)+pxPcx0b@3&!2M|b|1a?GDgOs3R%H~DrNPWNfO z2`kv8eMLK5+k^*jzfhU?Xxk-bwq90wL#wXVOYFBwX{R$oe*;X{yHB1!drF^>?yT2+ zqf<3C>LS{hLb8Gx8)>hULfb{_Lq?5nN`qQO8`pQk=% z&ai6$z5F5ti{tsi)+)2Uhv|=#v2|KRwz<(Kd-4xOEM%80U|&IhyW2F0z`la z5CI}U1c(3;_+JEW?k*KL$7jmd_iad*+AF`FGS7>NY7Msxu0We_1eA{EcjfDR1x)27 zQ`Os9wt`0$Co+Zu?1!`Ll&b)hPaM=LxKmK|$J_h6JFpIGffYs(v&{k1y>Q?d@npb~ z&>pa~IhGyRx(myoj(k70u7M^P#8EtSnQciLXiygnl8J6$DJE%9hlXIFN4o8@VI*nL zfTmy&d4cINHKTtGX@qw^{z{|r$dw1KJaOeCjjF}RM`?sDIL=DkzpkGC0H*!AegFUf diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c3a1.dat deleted file mode 100644 index 6b0fc39e3e659899eea177e1993df7fcc14a6083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI1zfQwI490z_)TaMio&lAq;?i8wL}FuO044^uOmz;T)?DxtSmwv?}q{iS#Lsmr-=4FCeKEG*JGX<3SXxrX`AGS__a0!)AjFaajO1egF5U;<2l z2`~XBuw4Wmo^AwO;X4)Q`z~Zh?VUewS@hQ%^#+a%Zoys+0xGlBQ^h%7z`j`I)!Os2 zn~ff_S->%zFFSLp;85ZXlZFK&*maeowG3xt>4fokI!Q1~V}C5Om?}T=od9Ye8eo&( z*GefFrY64)P4WlI*HT8(N zfC(^x?IQ5_d?Vlr->F*P_dzeUcmKR)RbMSMTexL#2ljF!VC`smSGCR;a3JQT+IU@5 z_11%h4{`$Mi^>eodSdGxQ_F%e?8SbPrczBD=|+hYcvclfMle^1G?4LOD%M{tk4>pGNT{lwoG_ccDjq=aq3P25}@J%KlH^aKu0ZZ4idH*cWNmXd;K zoXuatqkXUN!nc7eM8xR%8j+2ujbZThFsJiJF>2|L%aK-QdgdZ+zsYEGU4I>o?RSG) z$K4e?%O<*4y_jCm#OV^ z%iiAA*XxBe(_aQ_$;%%BjkEGD|DA87Z!RtypNndu*I3(+?J+5;2b&d1?k+(@009IL bKmY**5I_I{1Q0*~fgc5iGIcwTt^MfxGuieXjZk45o7=7~Aa(&|ZxC{9>rt@dfYT=K|v1aD_WFqab$!Kw1e{GHBkAr*1 zpNih)0^OSqrWY0Q`zpPwnXM}^76>4K00IagfB*srAbheKZoe|J&@T%=*ey3p z-@Y~E>xm@QD}#+>K-rbX_gV}2!JFWS)%KmY** a5I_I{1Q0*~0R#|0;1_|R%>4F)Jhm^H*DqcG diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat b/java/lance-namespace-hive3/metastore_db/seg0/c3f1.dat deleted file mode 100644 index 08acdcee31e218c5d9c3b4f62ef38fb0f42c8e72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI0F%H5o3`LzHwH@IGY>Y55aR$W95tsqN#?p}!a05=kDL6wJ7&rkqNmHezAhDun zDX#M!*UH;s*@}qKWi4?&bv||>A8Q&vD{ILgw+qdzb>$-caL8zL-G8;t_UGws=&PcC zIbl@l$4sIo{#?Vmp827nv4H>tAOHafKmY;|fB*y_009X6BZ1>-Z)Br43lHqXMcLb3 zL%y9zGaVTelGlTP&Zw>m?|dU;bM2TM$;ub(?#18*9@Q?- diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c400.dat b/java/lance-namespace-hive3/metastore_db/seg0/c400.dat deleted file mode 100644 index 1e8976f89fb63a0868c737d9434d15ecfdedc47c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#F%E(-6oBDZLa-qY-h#=*19*nUK?mdR3Dm^R)xi^ZCmCL&Ffo_&2!d+4ca%$v)#Ylsj)009ILKmY**5I_I{1Q0;r2Le+WS6z;m_3Z_e Cb`~Q5 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c41.dat b/java/lance-namespace-hive3/metastore_db/seg0/c41.dat deleted file mode 100644 index 81ddeed84ad99ee31dbbf74e2885d43ad152acaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeHOOKcle6g@Loy*AFpRG_e;C{e-j7g$iqDa_woO5qtdd!(ry2PRYluecT9iB!AqAP z704qiEqrOMQfhj9`yNG1U=aB(ib`$KJ5yw20CpbnP?Bj5$p8|eBr^;W;UX#ILlGHS zPI<*Eukr;+A|)_@T!(?Jhe#kTFoXf(sIRSijcW5Ont1b< zuTBoP>0??`@RiBn_D~X*Dp}m2uULy4)#_%koxna_D9*?fmJ-hyrE6y{7O*$otyvJQje+ zpYSAppzv85jZB~-AGZHN;oAyVv8*1ymyf!Ok3o1r;b9uJf24KoD+*i05WR#YiDg1N zquO6$QQpYEuJCo*u2rVb<8OtZD%_!UrT?GzYxw?;LuYpR|KpgHBh&t97v9YO2OqUV zl7RmH|3A5fuYZ_#KMBD96_}zNz&Ck4M4Vr7B28I91}XWIc0Ug#*y&CTpw?%XVy7qu z@S_z<5~?M>$B0r2;72Q(f;|r_Lm@y22}e#VOEG|-M>Jc~byvN8I7*SH9AE@Pa;J2$ zuuBqIiUPuUI8_Oi1azvZG+UK2doMX@3IRH^30T-wIVnm2{Moch3v1GsQtHDs4KA5~ ze>Pn#{Mls5{fF~#G$2D=s~NuEDARx}5@8Yf1+Ka7P_j}s^JAI8GkzX|gHeg^Sa#e1ABiHKud zUvGT^wjLse!vbR%k=Lh2eWO*W1?M1}DU!rp{h2uGMpC%DKNCmcNE#FROx#r+_X?B2 zJzD5Sozfz{JXstGpaiGbd*q0F$1DQVgzbHqNAZ?f^2}q4os05pr?nk9Y;l)hi%nywi4g??o0SG_<0uX=z1Rwwb2teQ;37m?(k*&Tge6SN|Wp8f{ z`F0}BbYyUpydDH}TJ@>$&o?qQrH}RoRo0Fk>?~j|t14qR+c>#e3xNOxAOHafKmY;| XfB*y_009U<;3onzS^N6pvV6P%AQ>&m diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c421.dat b/java/lance-namespace-hive3/metastore_db/seg0/c421.dat deleted file mode 100644 index 65775ee7bfbd1fe9a4e81f326933d49be9138b53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$Ee^sk6u|MxGuieXjZk3gY7=3JuT%Wi;?0i0q>HJx=TKMB~qM3z0nMm7jGFn{MUt44O4K00IagfB*srAbheK?yxqp)GzZt*pZv1 zZ{Oc{L6;HW?BpOap`f8a zza_u!EMNR}k*$b0?V)9HEaKQ5EZ>dk`rfuA{Bb+i%(}@A?a)Ard)s_7*M7N5?rJ}? zx@p`^M4m-@?u|A5z9&Nn0R#|0009ILKmY**5I_Kd{}MPHcTP6?Ci}n7;;MXmrR9@E zUg-IeyS~D?{&hs>8?kdI?JewM8f{y3d$X02B)(hZA@7T5XL)>{5De)RoQ z(Yst=aMzm|MMeC&TJLJ+`&x_%0tg_000IagfB*srAbfaii?* zUqil`NHaY$I7nU{1hkH-r@}tp$k5z;w6iF)_UOTupUJY!=my?>PIC1DdIS(a009IL YKmY**5I_I{1Q7T^U?MBOx_2t3FYvf6QUCw| diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c461.dat b/java/lance-namespace-hive3/metastore_db/seg0/c461.dat deleted file mode 100644 index e6d98541fb79659dd82e6c495be7eda4795dd219..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$u?@m75J1s$h#Z%UKu3#&M8ynr~rwMhLQ=`fQo6D0XjB-!;T{-1VoL# zB|G+=lT%)2%SJ?u_E*dNX#JQDF`veC{wP}`{Bb$e%u2fx>Bdb)i|hJpYb}2o-Fo4z z49z7(^F^7>_1V$#Gnr_gmsvf;Yg8n^hX5l22q1s} a0tg_000IagfB*sr{3tM%W!UMgJwE}e#Vuq2 diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c470.dat b/java/lance-namespace-hive3/metastore_db/seg0/c470.dat deleted file mode 100644 index c9f2eb1cae75e19bcc6f3d1feb17572a3f80c36e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#p$@_@5P;$9(u@iO9zjr8Bm%)BU=W0tKmZ92O@b%kvGx);9s!Qq%9b(&20{KV z>uz^VZ~fe4Cn8So=g4f%ZEjAn-ppxyuSSyo_&V3hrmXhjqOLX%@#UN6Ei6~bUe#xg zu9|makyn$JeXVCWv{XnTfB*srAbHJxYTKeO1q?Nf|xkx)~GJ3eKzmCS^4})9B zKNY>pCAwF=nSOML-&cw5%zRzRu|NO;1Q0*~0R#|0009ILK;Rz*cKel)g??H1!A{&P zd;8WUUorr~3;OQZJwY diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c51.dat b/java/lance-namespace-hive3/metastore_db/seg0/c51.dat deleted file mode 100644 index dfff21083bb55b7163ac47cd9d88d2a271c61eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 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 Lv(SfMKi>TVu>A~v diff --git a/java/lance-namespace-hive3/metastore_db/seg0/c90.dat b/java/lance-namespace-hive3/metastore_db/seg0/c90.dat deleted file mode 100644 index 25ed408e137a7afff470bc7ea34c04876fe58333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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 QKr-;Z#=!mGp8E5@0eJNGApigX diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cb1.dat b/java/lance-namespace-hive3/metastore_db/seg0/cb1.dat deleted file mode 100644 index 812444f3bf3fc51b41f0a02dcbe2667cd84debd5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI$e`wTo9LMq3-Q4}y&)aU>?e_ckcGKmr(rTI?%U@;wSmnxDty-3vX6mN7(z0c% z)Y__PW)uY#;U6Lu6d@H+Q4kVBKdAl?8AV|cQ4$6AzSnCf!&cFs!S`T~d*1iE+xPZ@ z4eqcRfX}{?H$M%~(WK6gK4yJ-=S{YePpl`p)(%@j9F)%m3q7F!$jYwBS#O9 z+$TSJ@Y@SnjE<2b19qRhu>Wl%==UKFz92%15W$W`Pb zqKF_*k%xRmKB9^!3KRt>R1~5}QG}QxhGIoA;)*y*6eTECl%h;ghH^zYDijr{R8*o$ zQH5$nHEI+!s8!UWPEm(?MLil64QNy}qDj$&gd%}vMKi`T`~gf*1ks`h;T%O66BQYl zq{zf%MHZ$gvN2VWgL4(RI8PD5G({e!EAnx^B8m$X1-MXAh*m`rW+-BqsVK%pia2H| zO5mKT6mGVv4DMo8Iou_x3b;9{O1QbID!6&7YPk8T8n^|jTDVJ9b#Rxd>fsiu8sIKh zHNq`YHNh=rr3K)YsDf}yRUx=GRT%CHRR-LZs!X`6R9SG#RM~LtsvNkhRk?82s3LI7 zRe5k7s(iQ=swmvGssgy{RE2QYtBT+{RWZ05RK;*Ns^V}rschXYm92ZT%GO<}vUP7! z*}Au?Y~58VTX(g})?K5rb#GJIx@%Ro?mCsNd%MckU9Ylr?@-yg8&nCnjjCq2O{{UY zc(=+H?@`&}n^m^>7L_f2r^*)JsZ1Klcw)hh&TYN}mi|y#_>-)3TYSID7Jo{W`af>}m%W>} zfVY6RfVY6Rz<*pIFdi8|pqj>LHcd;K{u}*~4%08`C-eh)guX&wrq9wLx{L0hTj)C4 zMVHehbS`bBlW8L@r%`HeG=OoZ=`ZwqdYpbnKc?@}H|Qby0zE(nX+PaYH__F!lP;qR z>1;Zkw$NG{r@1seY1;4fC;AQjnjWJc(zobq^dNnX?xTBXAKgmV)0K1uZKLz)Ogfb& zXeBMAnbeome~O-@C+HXSD1DEx`ZN8G9;ctvqx5}xguY4-(&y=ZIzapBcG^SN(k|LT+voy1i%z30w2qe2 ld>W=mic|ClI!wQ!$LL4&9r`*wL|>#cuttBX?SsFb{1bo$+ZF%- diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cc0.dat b/java/lance-namespace-hive3/metastore_db/seg0/cc0.dat deleted file mode 100644 index 226872006d7e7681f9732c7e2268f2312c42abd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI1y-or_5P;_d`8^c1va&H+ZL;?R90n5+qGABigF-C~aPS0bv@<4_))u~qrSS<& zd;v=n-$9){Zjr#!8#8-h*qynL-TN{P0G9xu;Y*AeKSumG8f1Mmhx6}XjHRb88(29X zRMYY%9XF53#gzA?Dt~fYD-QC*&kByY{(*Uo0}Kla-rqBJqo`1d43GgbKnBPF86X2> zfDDiUGC&5%!2dFE|9Gvz1wNDfexCvzSBn!*DeGf}a0JO^?QJCejPnrGp@kPjL$C&` zU2a$o=N{v{@32fKV=>cd=W!{9k?(nqgFgX8++(-0U4vN&6&nqR`7Cl`2-f4Q@8xpL z!uti=#;arGITr-75{yr5+F@qaHW<(Kx^h#??pr+Av{YL3pOymKmp?&Y+~H=qb@S= V>ckx5(_g!cb=gm8#4RL|*JS^htr_`8HUa5uVga3OcH{e2zUYA=4frH#)9JYPlzHwdPKfWqCh%J%sVHk_ACea_xGdeB)w ziqlMaG>Qx*bmO}+CGe7yB-}kf3677z#XL%)s2iYc6FTjIDrHoxvX}N%si5kj3|~s( z=`Msvy5C)_a3a_Md RtIj>O58!+O>G0`x?-%c{mUjRE diff --git a/java/lance-namespace-hive3/metastore_db/seg0/cf0.dat b/java/lance-namespace-hive3/metastore_db/seg0/cf0.dat deleted file mode 100644 index fb40ee421916f7cc965275d19623aec219c8c959..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u?@m75J1s$gc27NtU#5P7Ks_6G!%$60Evzoi3wPT4OoJX41fg3B}SGB1q}uI zj&gDCEMNS($VNn*-p`R)%q_+t)Z?7a@7+k!A75*&tlH`*EE;NaA6~wBUj1U3?A3i{ zdC|O^h`gHg>}x&!uBSo@0R#|0009ILKmY**5I_Kd{}MPHw@%i2rtp8C*{pawWvC~G zL9Xk^?i{5XoflH+HMdwv9aWhkfB*srAbmQns!3)6?w%oG2D4 diff --git a/java/lance-namespace-hive3/metastore_db/service.properties b/java/lance-namespace-hive3/metastore_db/service.properties deleted file mode 100644 index 2647898..0000000 --- a/java/lance-namespace-hive3/metastore_db/service.properties +++ /dev/null @@ -1,23 +0,0 @@ -#/Users/zhaoqinye/oss/lance-namespace-impls/java/lance-namespace-hive3/metastore_db -# ******************************************************************** -# *** Please do NOT edit this file. *** -# *** CHANGING THE CONTENT OF THIS FILE MAY CAUSE DATA CORRUPTION. *** -# ******************************************************************** -#Tue Dec 30 21:25:14 PST 2025 -SysconglomeratesIdentifier=32 -SyscolumnsIdentifier=144 -derby.serviceLocale=en_US -SystablesIdentifier=96 -SysconglomeratesIndex3Identifier=81 -derby.storage.propertiesId=16 -derby.serviceProtocol=org.apache.derby.database.Database -SyscolumnsIndex1Identifier=161 -SysschemasIndex2Identifier=225 -SystablesIndex2Identifier=129 -SyscolumnsIndex2Identifier=177 -SysconglomeratesIndex2Identifier=65 -SysschemasIndex1Identifier=209 -SysschemasIdentifier=192 -SystablesIndex1Identifier=113 -SysconglomeratesIndex1Identifier=49 -#--- last line, don't put anything after this line --- From 1f21bc9098eda3df241a9027fbce37f72a6ed6e3 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 22:25:04 -0800 Subject: [PATCH 07/20] fix iceberg --- .github/workflows/java-integ-iceberg.yml | 105 +++++++ .github/workflows/python-integ-iceberg.yml | 112 +++++++ Makefile | 16 +- docker/Makefile | 18 +- docker/lakekeeper/docker-compose.yml | 162 ++++++++++ java/Makefile | 6 +- java/lance-namespace-iceberg/pom.xml | 20 +- .../namespace/iceberg/IcebergModels.java | 25 ++ .../namespace/iceberg/IcebergNamespace.java | 170 ++++++++--- .../iceberg/IcebergNamespaceConfig.java | 4 + .../TestIcebergNamespaceIntegration.java | 280 ++++++++++++++++++ python/Makefile | 4 + python/src/lance_namespace_impls/iceberg.py | 240 +++++++++++---- python/tests/test_iceberg_integration.py | 223 ++++++++++++++ 14 files changed, 1277 insertions(+), 108 deletions(-) create mode 100644 .github/workflows/java-integ-iceberg.yml create mode 100644 .github/workflows/python-integ-iceberg.yml create mode 100644 docker/lakekeeper/docker-compose.yml create mode 100644 java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java create mode 100644 python/tests/test_iceberg_integration.py diff --git a/.github/workflows/java-integ-iceberg.yml b/.github/workflows/java-integ-iceberg.yml new file mode 100644 index 0000000..e13625c --- /dev/null +++ b/.github/workflows/java-integ-iceberg.yml @@ -0,0 +1,105 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Iceberg Integration + +on: + push: + branches: + - main + paths: + - java/lance-namespace-iceberg/** + - docker/lakekeeper/** + - .github/workflows/java-integ-iceberg.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-iceberg/** + - docker/lakekeeper/** + - .github/workflows/java-integ-iceberg.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + cache: "maven" + - name: Start Iceberg REST Catalog (Lakekeeper) + run: make docker-up-iceberg + - name: Wait for Iceberg REST Catalog + run: | + echo "Waiting for Iceberg REST Catalog to be ready..." + timeout 180 bash -c ' + until curl -sf http://localhost:8282/health > /dev/null 2>&1; do + echo "Waiting for health endpoint..." + sleep 5 + done + ' || { + echo "Timeout waiting for Iceberg REST Catalog" + docker compose -f docker/lakekeeper/docker-compose.yml logs + exit 1 + } + echo "Iceberg REST Catalog is ready" + + # Wait for setup to complete (creates test_warehouse) + echo "Waiting for warehouse setup to complete..." + timeout 60 bash -c ' + while docker ps -q -f name=lakekeeper-setup 2>/dev/null | grep -q .; do + echo "Waiting for setup container to finish..." + sleep 2 + done + ' || echo "Setup may have already completed" + + # Verify warehouse exists + echo "Verifying test_warehouse exists..." + WAREHOUSES=$(curl -s http://localhost:8282/management/v1/warehouse || echo "") + + if echo "$WAREHOUSES" | grep -q "test_warehouse"; then + echo "test_warehouse verified" + else + echo "Warning: test_warehouse not found in warehouses: $WAREHOUSES" + docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper-setup + fi + - name: Build + run: make build-java + - name: Run integration tests + run: make java-integ-test-iceberg + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose Status ===" + docker compose -f docker/lakekeeper/docker-compose.yml ps + echo "" + echo "=== Iceberg REST Catalog Logs ===" + docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper + echo "" + echo "=== PostgreSQL Logs ===" + docker compose -f docker/lakekeeper/docker-compose.yml logs postgres-lakekeeper + - name: Cleanup + if: always() + run: make docker-down-iceberg diff --git a/.github/workflows/python-integ-iceberg.yml b/.github/workflows/python-integ-iceberg.yml new file mode 100644 index 0000000..d6d8a3b --- /dev/null +++ b/.github/workflows/python-integ-iceberg.yml @@ -0,0 +1,112 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Iceberg Integration + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/src/lance_namespace_impls/rest_client.py + - python/tests/test_iceberg.py + - python/tests/test_iceberg_integration.py + - docker/lakekeeper/** + - .github/workflows/python-integ-iceberg.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/iceberg.py + - python/src/lance_namespace_impls/rest_client.py + - python/tests/test_iceberg.py + - python/tests/test_iceberg_integration.py + - docker/lakekeeper/** + - .github/workflows/python-integ-iceberg.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + uses: astral-sh/setup-uv@v4 + - name: Start Iceberg REST Catalog (Lakekeeper) + run: make docker-up-iceberg + - name: Wait for Iceberg REST Catalog + run: | + echo "Waiting for Iceberg REST Catalog to be ready..." + timeout 180 bash -c ' + until curl -sf http://localhost:8282/health > /dev/null 2>&1; do + echo "Waiting for health endpoint..." + sleep 5 + done + ' || { + echo "Timeout waiting for Iceberg REST Catalog" + docker compose -f docker/lakekeeper/docker-compose.yml logs + exit 1 + } + echo "Iceberg REST Catalog is ready" + + # Wait for setup to complete (creates test_warehouse) + echo "Waiting for warehouse setup to complete..." + timeout 60 bash -c ' + while docker ps -q -f name=lakekeeper-setup 2>/dev/null | grep -q .; do + echo "Waiting for setup container to finish..." + sleep 2 + done + ' || echo "Setup may have already completed" + + # Verify warehouse exists + echo "Verifying test_warehouse exists..." + WAREHOUSES=$(curl -s http://localhost:8282/management/v1/warehouse || echo "") + + if echo "$WAREHOUSES" | grep -q "test_warehouse"; then + echo "test_warehouse verified" + else + echo "Warning: test_warehouse not found in warehouses: $WAREHOUSES" + docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper-setup + fi + - name: Install dependencies + working-directory: python + run: make install-iceberg + - name: Run integration tests + run: make python-integ-test-iceberg + - name: Collect logs on failure + if: failure() + run: | + echo "=== Docker Compose Status ===" + docker compose -f docker/lakekeeper/docker-compose.yml ps + echo "" + echo "=== Iceberg REST Catalog Logs ===" + docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper + echo "" + echo "=== PostgreSQL Logs ===" + docker compose -f docker/lakekeeper/docker-compose.yml logs postgres-lakekeeper + - name: Cleanup + if: always() + run: make docker-down-iceberg diff --git a/Makefile b/Makefile index 82625f3..5ec78e1 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,7 @@ docker-logs: cd docker && make logs # Individual catalog docker targets -.PHONY: docker-up-hive2 docker-up-hive3 docker-up-polaris docker-up-unity +.PHONY: docker-up-hive2 docker-up-hive3 docker-up-polaris docker-up-unity docker-up-iceberg docker-up-hive2: cd docker && make up-hive2 docker-up-hive3: @@ -109,8 +109,10 @@ docker-up-polaris: cd docker && make up-polaris docker-up-unity: cd docker && make up-unity +docker-up-iceberg: + cd docker && make up-iceberg -.PHONY: docker-down-hive2 docker-down-hive3 docker-down-polaris docker-down-unity +.PHONY: docker-down-hive2 docker-down-hive3 docker-down-polaris docker-down-unity docker-down-iceberg docker-down-hive2: cd docker && make down-hive2 docker-down-hive3: @@ -119,6 +121,8 @@ docker-down-polaris: cd docker && make down-polaris docker-down-unity: cd docker && make down-unity +docker-down-iceberg: + cd docker && make down-iceberg # ============================================================================ # Java Integration test targets @@ -140,6 +144,10 @@ java-integ-test-hive3: java-integ-test-polaris: cd java && make integ-test-polaris +.PHONY: java-integ-test-iceberg +java-integ-test-iceberg: + cd java && make integ-test-iceberg + .PHONY: java-integ-test-unity java-integ-test-unity: cd java && make integ-test-unity @@ -171,3 +179,7 @@ python-integ-test-polaris: .PHONY: python-integ-test-unity python-integ-test-unity: cd python && make integ-test-unity + +.PHONY: python-integ-test-iceberg +python-integ-test-iceberg: + cd python && make integ-test-iceberg diff --git a/docker/Makefile b/docker/Makefile index 449cb16..8d2f99a 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -18,7 +18,7 @@ POSTGRES_DRIVER_VERSION := 42.7.3 POSTGRES_DRIVER_URL := https://jdbc.postgresql.org/download/postgresql-$(POSTGRES_DRIVER_VERSION).jar .PHONY: setup up down down-clean logs status health -.PHONY: up-hive2 down-hive2 up-hive3 down-hive3 up-polaris down-polaris up-unity down-unity +.PHONY: up-hive2 down-hive2 up-hive3 down-hive3 up-polaris down-polaris up-unity down-unity up-iceberg down-iceberg # Download PostgreSQL JDBC driver for Hive setup: @@ -60,6 +60,9 @@ health: @echo "" @echo "=== Unity Catalog (port 8080) ===" @curl -sf http://localhost:8080/api/2.1/unity-catalog/catalogs > /dev/null && echo "OK" || echo "NOT READY" + @echo "" + @echo "=== Iceberg REST Catalog (port 8282) ===" + @curl -sf http://localhost:8282/health > /dev/null && echo "OK" || echo "NOT READY" # ============================================================================ # Individual service management @@ -117,6 +120,19 @@ down-unity-clean: logs-unity: docker compose -f unity/docker-compose.yml logs -f +# Iceberg REST Catalog (Lakekeeper) +up-iceberg: + docker compose -f lakekeeper/docker-compose.yml up -d + +down-iceberg: + docker compose -f lakekeeper/docker-compose.yml down + +down-iceberg-clean: + docker compose -f lakekeeper/docker-compose.yml down -v + +logs-iceberg: + docker compose -f lakekeeper/docker-compose.yml logs -f + # ============================================================================ # Test utilities # ============================================================================ diff --git a/docker/lakekeeper/docker-compose.yml b/docker/lakekeeper/docker-compose.yml new file mode 100644 index 0000000..36dd394 --- /dev/null +++ b/docker/lakekeeper/docker-compose.yml @@ -0,0 +1,162 @@ +services: + postgres-lakekeeper: + image: postgres:17 + container_name: postgres-lakekeeper + environment: + POSTGRES_USER: lakekeeper + POSTGRES_PASSWORD: lakekeeper + POSTGRES_DB: lakekeeper + ports: + - "5435:5432" + volumes: + - lakekeeper-postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U lakekeeper -d lakekeeper"] + interval: 2s + timeout: 10s + retries: 5 + networks: + - lakekeeper-network + + minio: + image: minio/minio:latest + container_name: minio-lakekeeper + environment: + MINIO_ROOT_USER: minio-root-user + MINIO_ROOT_PASSWORD: minio-root-password + MINIO_DOMAIN: minio + command: server /data --console-address ":9001" + ports: + - "19000:9000" + - "19001:9001" + volumes: + - lakekeeper-minio-data:/data + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 2s + timeout: 10s + retries: 5 + networks: + - lakekeeper-network + + minio-setup: + image: minio/mc:latest + container_name: minio-setup + depends_on: + minio: + condition: service_healthy + entrypoint: > + /bin/sh -c " + mc alias set myminio http://minio:9000 minio-root-user minio-root-password && + mc mb myminio/warehouse --ignore-existing && + echo 'MinIO bucket created' + " + networks: + - lakekeeper-network + + lakekeeper-migrate: + image: quay.io/lakekeeper/catalog:latest-main + container_name: lakekeeper-migrate + depends_on: + postgres-lakekeeper: + condition: service_healthy + environment: + - LAKEKEEPER__PG_ENCRYPTION_KEY=test-encryption-key-not-secure + - LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://lakekeeper:lakekeeper@postgres-lakekeeper:5432/lakekeeper + - LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://lakekeeper:lakekeeper@postgres-lakekeeper:5432/lakekeeper + restart: "no" + command: ["migrate"] + networks: + - lakekeeper-network + + lakekeeper: + image: quay.io/lakekeeper/catalog:latest-main + container_name: lakekeeper + depends_on: + lakekeeper-migrate: + condition: service_completed_successfully + minio-setup: + condition: service_completed_successfully + environment: + - LAKEKEEPER__PG_ENCRYPTION_KEY=test-encryption-key-not-secure + - LAKEKEEPER__PG_DATABASE_URL_READ=postgresql://lakekeeper:lakekeeper@postgres-lakekeeper:5432/lakekeeper + - LAKEKEEPER__PG_DATABASE_URL_WRITE=postgresql://lakekeeper:lakekeeper@postgres-lakekeeper:5432/lakekeeper + - LAKEKEEPER__AUTHZ_BACKEND=allowall + - RUST_LOG=info + command: ["serve"] + healthcheck: + test: ["CMD", "/home/nonroot/lakekeeper", "healthcheck"] + interval: 2s + timeout: 10s + retries: 5 + start_period: 5s + ports: + - "8282:8181" + networks: + - lakekeeper-network + + lakekeeper-bootstrap: + image: curlimages/curl + container_name: lakekeeper-bootstrap + depends_on: + lakekeeper: + condition: service_healthy + restart: "no" + command: + - -w + - "%{http_code}" + - "-X" + - "POST" + - "-v" + - "http://lakekeeper:8181/management/v1/bootstrap" + - "-H" + - "Content-Type: application/json" + - "--data" + - '{"accept-terms-of-use": true}' + - "-o" + - "/dev/null" + networks: + - lakekeeper-network + + lakekeeper-setup: + image: curlimages/curl + container_name: lakekeeper-setup + depends_on: + lakekeeper-bootstrap: + condition: service_completed_successfully + restart: "no" + entrypoint: ["/bin/sh", "-c"] + command: + - | + echo "Creating test_warehouse..." + curl -sf -X POST "http://lakekeeper:8181/management/v1/warehouse" \ + -H "Content-Type: application/json" \ + -d '{ + "warehouse-name": "test_warehouse", + "project-id": "00000000-0000-0000-0000-000000000000", + "storage-profile": { + "type": "s3", + "bucket": "warehouse", + "endpoint": "http://minio:9000", + "region": "us-east-1", + "path-style-access": true, + "flavor": "minio", + "sts-enabled": false + }, + "storage-credential": { + "type": "s3", + "credential-type": "access-key", + "aws-access-key-id": "minio-root-user", + "aws-secret-access-key": "minio-root-password" + } + }' && echo "Warehouse created successfully" || echo "Failed to create warehouse" + networks: + - lakekeeper-network + +volumes: + lakekeeper-postgres-data: + lakekeeper-minio-data: + +networks: + lakekeeper-network: + driver: bridge diff --git a/java/Makefile b/java/Makefile index 7eef02f..4500848 100644 --- a/java/Makefile +++ b/java/Makefile @@ -76,7 +76,7 @@ build-iceberg: .PHONY: test-iceberg test-iceberg: - ./mvnw test -pl lance-namespace-iceberg + ./mvnw test -pl lance-namespace-iceberg -Dtest="!*IntegrationTest" # ============================================================================ # Polaris @@ -153,6 +153,10 @@ integ-test-hive3: integ-test-polaris: ./mvnw test -pl lance-namespace-polaris -Dtest="*Integration" -DfailIfNoTests=false +.PHONY: integ-test-iceberg +integ-test-iceberg: + ./mvnw test -pl lance-namespace-iceberg -Dtest="*Integration" -DfailIfNoTests=false + .PHONY: integ-test-unity integ-test-unity: ./mvnw test -pl lance-namespace-unity -Dtest="*IntegrationTest" -DfailIfNoTests=false diff --git a/java/lance-namespace-iceberg/pom.xml b/java/lance-namespace-iceberg/pom.xml index b3d2eb5..bfa5d9d 100644 --- a/java/lance-namespace-iceberg/pom.xml +++ b/java/lance-namespace-iceberg/pom.xml @@ -56,20 +56,28 @@ - junit - junit + org.junit.jupiter + junit-jupiter test - org.mockito mockito-core test - - org.slf4j - slf4j-simple + org.mockito + mockito-junit-jupiter + test + + + org.assertj + assertj-core + test + + + ch.qos.logback + logback-classic test diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java index 4754fc2..b177e58 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergModels.java @@ -418,6 +418,31 @@ public void setConfig(Map config) { } } + @JsonIgnoreProperties(ignoreUnknown = true) + public static class ConfigResponse { + @JsonProperty("defaults") + private Map defaults; + + @JsonProperty("overrides") + private Map overrides; + + public Map getDefaults() { + return defaults; + } + + public void setDefaults(Map defaults) { + this.defaults = defaults; + } + + public Map getOverrides() { + return overrides; + } + + public void setOverrides(Map overrides) { + this.overrides = overrides; + } + } + public static IcebergSchema createDummySchema() { IcebergSchema schema = new IcebergSchema(); schema.setType("struct"); diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java index 4661d69..5a76aa6 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java @@ -60,7 +60,18 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -/** Iceberg REST Catalog namespace implementation for Lance. */ +/** + * Iceberg REST Catalog namespace implementation for Lance. + * + *

The prefix (warehouse) is included in the namespace identifier: + * + *

+ * + *

This is consistent with how Polaris handles catalog names. + */ public class IcebergNamespace implements LanceNamespace, Closeable { private static final Logger LOG = LoggerFactory.getLogger(IcebergNamespace.class); private static final String TABLE_TYPE_LANCE = "lance"; @@ -70,6 +81,7 @@ public class IcebergNamespace implements LanceNamespace, Closeable { private IcebergNamespaceConfig config; private RestClient restClient; private BufferAllocator allocator; + private final Map prefixCache = new HashMap<>(); public IcebergNamespace() {} @@ -80,7 +92,7 @@ public void initialize(Map configProperties, BufferAllocator all RestClient.Builder clientBuilder = RestClient.builder() - .baseUrl(config.getFullApiUrl()) + .baseUrl(config.getBaseApiUrl()) .connectTimeout(config.getConnectTimeout(), TimeUnit.MILLISECONDS) .readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS) .maxRetries(config.getMaxRetries()); @@ -101,6 +113,37 @@ public String namespaceId() { return String.format("IcebergNamespace { endpoint: \"%s\" }", config.getEndpoint()); } + private String resolvePrefix(String warehouse) { + if (prefixCache.containsKey(warehouse)) { + return prefixCache.get(warehouse); + } + + try { + Map params = new HashMap<>(); + params.put("warehouse", warehouse); + IcebergModels.ConfigResponse response = + restClient.get("/v1/config", params, IcebergModels.ConfigResponse.class); + if (response != null + && response.getDefaults() != null + && response.getDefaults().get("prefix") != null) { + String prefix = response.getDefaults().get("prefix"); + prefixCache.put(warehouse, prefix); + LOG.debug("Resolved warehouse '{}' to prefix '{}'", warehouse, prefix); + return prefix; + } + } catch (Exception e) { + LOG.debug("Failed to resolve prefix for warehouse '{}': {}", warehouse, e.getMessage()); + } + + prefixCache.put(warehouse, warehouse); + return warehouse; + } + + private String getPrefixPath(String warehouse) { + String prefix = resolvePrefix(warehouse); + return "/v1/" + prefix; + } + @Override public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ObjectIdentifier nsId = @@ -108,10 +151,20 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { ? ObjectIdentifier.of(request.getId()) : ObjectIdentifier.of(Collections.emptyList()); + ValidationUtil.checkArgument( + nsId.levels() >= 1, "Must specify at least the prefix (warehouse)"); + try { + String prefix = nsId.levelAtListPos(0); + List parentNs = + nsId.levels() > 1 + ? nsId.listStyleId().subList(1, nsId.levels()) + : Collections.emptyList(); + String prefixPath = getPrefixPath(prefix); + Map params = new HashMap<>(); - if (nsId.levels() > 0) { - String parent = encodeNamespace(nsId.listStyleId()); + if (!parentNs.isEmpty()) { + String parent = encodeNamespace(parentNs); params.put("parent", parent); } if (request.getPageToken() != null) { @@ -120,14 +173,19 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { IcebergModels.ListNamespacesResponse response = params.isEmpty() - ? restClient.get("/namespaces", IcebergModels.ListNamespacesResponse.class) - : restClient.get("/namespaces", params, IcebergModels.ListNamespacesResponse.class); + ? restClient.get( + prefixPath + "/namespaces", IcebergModels.ListNamespacesResponse.class) + : restClient.get( + prefixPath + "/namespaces", params, IcebergModels.ListNamespacesResponse.class); List namespaces = new ArrayList<>(); if (response != null && response.getNamespaces() != null) { for (List ns : response.getNamespaces()) { if (!ns.isEmpty()) { - namespaces.add(ns.get(ns.size() - 1)); + List fullNs = new ArrayList<>(); + fullNs.add(prefix); + fullNs.addAll(ns); + namespaces.add(String.join(".", fullNs)); } } } @@ -146,19 +204,26 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { @Override public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); - ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); + ValidationUtil.checkArgument( + nsId.levels() >= 2, "Namespace must have at least prefix and namespace levels"); try { + String prefix = nsId.levelAtListPos(0); + List namespace = nsId.listStyleId().subList(1, nsId.levels()); + String prefixPath = getPrefixPath(prefix); + IcebergModels.CreateNamespaceRequest createRequest = new IcebergModels.CreateNamespaceRequest(); - createRequest.setNamespace(nsId.listStyleId()); + createRequest.setNamespace(namespace); createRequest.setProperties(request.getProperties()); IcebergModels.CreateNamespaceResponse response = restClient.post( - "/namespaces", createRequest, IcebergModels.CreateNamespaceResponse.class); + prefixPath + "/namespaces", + createRequest, + IcebergModels.CreateNamespaceResponse.class); - LOG.info("Created namespace: {}", nsId.stringStyleId()); + LOG.info("Created namespace: {}.{}", prefix, String.join(".", namespace)); CreateNamespaceResponse result = new CreateNamespaceResponse(); result.setProperties(response != null ? response.getProperties() : null); @@ -175,12 +240,19 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { @Override public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest request) { ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); - ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); + ValidationUtil.checkArgument( + nsId.levels() >= 2, "Namespace must have at least prefix and namespace levels"); try { - String namespacePath = encodeNamespace(nsId.listStyleId()); + String prefix = nsId.levelAtListPos(0); + List namespace = nsId.listStyleId().subList(1, nsId.levels()); + String prefixPath = getPrefixPath(prefix); + String namespacePath = encodeNamespace(namespace); + IcebergModels.GetNamespaceResponse response = - restClient.get("/namespaces/" + namespacePath, IcebergModels.GetNamespaceResponse.class); + restClient.get( + prefixPath + "/namespaces/" + namespacePath, + IcebergModels.GetNamespaceResponse.class); DescribeNamespaceResponse result = new DescribeNamespaceResponse(); result.setProperties(response != null ? response.getProperties() : null); @@ -201,12 +273,17 @@ public void namespaceExists(NamespaceExistsRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); - ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); + ValidationUtil.checkArgument( + nsId.levels() >= 2, "Namespace must have at least prefix and namespace levels"); try { - String namespacePath = encodeNamespace(nsId.listStyleId()); - restClient.delete("/namespaces/" + namespacePath); - LOG.info("Dropped namespace: {}", nsId.stringStyleId()); + String prefix = nsId.levelAtListPos(0); + List namespace = nsId.listStyleId().subList(1, nsId.levels()); + String prefixPath = getPrefixPath(prefix); + String namespacePath = encodeNamespace(namespace); + + restClient.delete(prefixPath + "/namespaces/" + namespacePath); + LOG.info("Dropped namespace: {}.{}", prefix, String.join(".", namespace)); return new DropNamespaceResponse(); } catch (RestClientException e) { if (e.isNotFound()) { @@ -219,10 +296,14 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { @Override public ListTablesResponse listTables(ListTablesRequest request) { ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); - ValidationUtil.checkArgument(nsId.levels() >= 1, "Namespace must have at least one level"); + ValidationUtil.checkArgument(nsId.levels() >= 2, "Must specify at least prefix and namespace"); try { - String namespacePath = encodeNamespace(nsId.listStyleId()); + String prefix = nsId.levelAtListPos(0); + List namespace = nsId.listStyleId().subList(1, nsId.levels()); + String prefixPath = getPrefixPath(prefix); + String namespacePath = encodeNamespace(namespace); + Map params = new HashMap<>(); if (request.getPageToken() != null) { params.put("pageToken", request.getPageToken()); @@ -231,17 +312,17 @@ public ListTablesResponse listTables(ListTablesRequest request) { IcebergModels.ListTablesResponse response = params.isEmpty() ? restClient.get( - "/namespaces/" + namespacePath + "/tables", + prefixPath + "/namespaces/" + namespacePath + "/tables", IcebergModels.ListTablesResponse.class) : restClient.get( - "/namespaces/" + namespacePath + "/tables", + prefixPath + "/namespaces/" + namespacePath + "/tables", params, IcebergModels.ListTablesResponse.class); List tables = new ArrayList<>(); if (response != null && response.getIdentifiers() != null) { for (IcebergModels.TableIdentifier tableId : response.getIdentifiers()) { - if (isLanceTable(nsId.listStyleId(), tableId.getName())) { + if (isLanceTable(prefix, namespace, tableId.getName())) { tables.add(tableId.getName()); } } @@ -265,15 +346,19 @@ public ListTablesResponse listTables(ListTablesRequest request) { public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); + tableId.levels() >= 3, "Table identifier must have prefix, namespace, and table name"); - List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); + String prefix = tableId.levelAtListPos(0); + List namespace = tableId.listStyleId().subList(1, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { + String prefixPath = getPrefixPath(prefix); + String tablePath = request.getLocation(); if (tablePath == null || tablePath.isEmpty()) { - tablePath = config.getRoot() + "/" + String.join("/", namespace) + "/" + tableName; + List pathParts = tableId.listStyleId().subList(0, tableId.levels() - 1); + tablePath = config.getRoot() + "/" + String.join("/", pathParts) + "/" + tableName; } IcebergModels.CreateTableRequest createRequest = new IcebergModels.CreateTableRequest(); @@ -288,11 +373,11 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request String namespacePath = encodeNamespace(namespace); IcebergModels.LoadTableResponse response = restClient.post( - "/namespaces/" + namespacePath + "/tables", + prefixPath + "/namespaces/" + namespacePath + "/tables", createRequest, IcebergModels.LoadTableResponse.class); - LOG.info("Created Lance table: {}.{}", namespacePath, tableName); + LOG.info("Created Lance table: {}", tableId.stringStyleId()); CreateEmptyTableResponse result = new CreateEmptyTableResponse(); result.setLocation(tablePath); @@ -302,7 +387,8 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request throw new TableAlreadyExistsException("Table already exists: " + tableId.stringStyleId()); } if (e.isNotFound()) { - throw new NamespaceNotFoundException("Namespace not found: " + String.join(".", namespace)); + throw new NamespaceNotFoundException( + "Namespace not found: " + prefix + "." + String.join(".", namespace)); } throw new InternalException("Failed to create table: " + e.getMessage()); } @@ -312,18 +398,20 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request public DescribeTableResponse describeTable(DescribeTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); + tableId.levels() >= 3, "Table identifier must have prefix, namespace, and table name"); - List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); + String prefix = tableId.levelAtListPos(0); + List namespace = tableId.listStyleId().subList(1, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { + String prefixPath = getPrefixPath(prefix); String namespacePath = encodeNamespace(namespace); String encodedTableName = urlEncode(tableName); IcebergModels.LoadTableResponse response = restClient.get( - "/namespaces/" + namespacePath + "/tables/" + encodedTableName, + prefixPath + "/namespaces/" + namespacePath + "/tables/" + encodedTableName, IcebergModels.LoadTableResponse.class); if (response == null || response.getMetadata() == null) { @@ -359,18 +447,20 @@ public void tableExists(TableExistsRequest request) { public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( - tableId.levels() >= 2, "Table identifier must have at least namespace and table name"); + tableId.levels() >= 3, "Table identifier must have prefix, namespace, and table name"); - List namespace = tableId.listStyleId().subList(0, tableId.levels() - 1); + String prefix = tableId.levelAtListPos(0); + List namespace = tableId.listStyleId().subList(1, tableId.levels() - 1); String tableName = tableId.levelAtListPos(tableId.levels() - 1); try { + String prefixPath = getPrefixPath(prefix); String namespacePath = encodeNamespace(namespace); String encodedTableName = urlEncode(tableName); IcebergModels.LoadTableResponse getResponse = restClient.get( - "/namespaces/" + namespacePath + "/tables/" + encodedTableName, + prefixPath + "/namespaces/" + namespacePath + "/tables/" + encodedTableName, IcebergModels.LoadTableResponse.class); String location = null; @@ -378,8 +468,9 @@ public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { location = getResponse.getMetadata().getLocation(); } - restClient.delete("/namespaces/" + namespacePath + "/tables/" + encodedTableName); - LOG.info("Deregistered table: {}.{}", namespacePath, tableName); + restClient.delete( + prefixPath + "/namespaces/" + namespacePath + "/tables/" + encodedTableName); + LOG.info("Deregistered table: {}", tableId.stringStyleId()); DeregisterTableResponse result = new DeregisterTableResponse(); result.setLocation(location); @@ -415,14 +506,15 @@ private String urlEncode(String s) { } } - private boolean isLanceTable(List namespace, String tableName) { + private boolean isLanceTable(String prefix, List namespace, String tableName) { try { + String prefixPath = getPrefixPath(prefix); String namespacePath = encodeNamespace(namespace); String encodedTableName = urlEncode(tableName); IcebergModels.LoadTableResponse response = restClient.get( - "/namespaces/" + namespacePath + "/tables/" + encodedTableName, + prefixPath + "/namespaces/" + namespacePath + "/tables/" + encodedTableName, IcebergModels.LoadTableResponse.class); if (response != null && response.getMetadata() != null) { diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java index f5bc7a5..438fa5c 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java @@ -97,4 +97,8 @@ public String getFullApiUrl() { } return base; } + + public String getBaseApiUrl() { + return endpoint.endsWith("/") ? endpoint.substring(0, endpoint.length() - 1) : endpoint; + } } diff --git a/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java b/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java new file mode 100644 index 0000000..329756e --- /dev/null +++ b/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java @@ -0,0 +1,280 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.iceberg; + +import org.lance.namespace.errors.LanceNamespaceException; +import org.lance.namespace.model.CreateEmptyTableRequest; +import org.lance.namespace.model.CreateEmptyTableResponse; +import org.lance.namespace.model.CreateNamespaceRequest; +import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DescribeNamespaceRequest; +import org.lance.namespace.model.DescribeNamespaceResponse; +import org.lance.namespace.model.DescribeTableRequest; +import org.lance.namespace.model.DescribeTableResponse; +import org.lance.namespace.model.DropNamespaceRequest; +import org.lance.namespace.model.ListNamespacesRequest; +import org.lance.namespace.model.ListNamespacesResponse; +import org.lance.namespace.model.ListTablesRequest; +import org.lance.namespace.model.ListTablesResponse; +import org.lance.namespace.model.NamespaceExistsRequest; +import org.lance.namespace.model.TableExistsRequest; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Integration tests for IcebergNamespace against a running Iceberg REST Catalog. + * + *

This test uses Lakekeeper as the Iceberg REST Catalog implementation. To run these tests, + * start the catalog with: + * + *

+ *   cd docker/lakekeeper && docker-compose up -d
+ * 
+ * + *

Tests are automatically skipped if the catalog is not available. + */ +public class TestIcebergNamespaceIntegration { + + private static final String ICEBERG_ENDPOINT = "http://localhost:8282/catalog"; + private static final String TEST_WAREHOUSE = "test_warehouse"; + private static boolean icebergAvailable = false; + + private IcebergNamespace namespace; + private BufferAllocator allocator; + private String testNamespace; + + @BeforeAll + public static void checkIcebergAvailable() { + try { + URL url = new URL(ICEBERG_ENDPOINT + "/v1/config?warehouse=" + TEST_WAREHOUSE); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(5000); + conn.setReadTimeout(5000); + + int responseCode = conn.getResponseCode(); + conn.disconnect(); + + icebergAvailable = responseCode == 200; + + if (!icebergAvailable) { + System.out.println( + "Iceberg REST Catalog is not available at " + + ICEBERG_ENDPOINT + + " - skipping integration tests"); + } else { + System.out.println( + "Iceberg REST Catalog detected at " + + ICEBERG_ENDPOINT + + " (response code: " + + responseCode + + ")"); + } + } catch (Exception e) { + icebergAvailable = false; + System.out.println( + "Iceberg REST Catalog is not available at " + + ICEBERG_ENDPOINT + + " (" + + e.getMessage() + + ") - skipping integration tests"); + } + } + + @BeforeEach + public void setUp() throws Exception { + Assumptions.assumeTrue( + icebergAvailable, "Iceberg REST Catalog is not available at " + ICEBERG_ENDPOINT); + + allocator = new RootAllocator(); + namespace = new IcebergNamespace(); + + String uniqueId = UUID.randomUUID().toString().substring(0, 8); + testNamespace = "test_ns_" + uniqueId; + + Map config = new HashMap<>(); + config.put("endpoint", ICEBERG_ENDPOINT); + config.put("root", "s3://warehouse"); + + namespace.initialize(config, allocator); + } + + @AfterEach + public void tearDown() { + try { + DropNamespaceRequest dropRequest = new DropNamespaceRequest(); + dropRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.dropNamespace(dropRequest); + } catch (Exception e) { + // Ignore cleanup errors + } + + if (allocator != null) { + allocator.close(); + } + } + + @Test + public void testNamespaceOperations() { + // Create namespace + CreateNamespaceRequest createRequest = new CreateNamespaceRequest(); + createRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + createRequest.setProperties(Collections.singletonMap("description", "Test namespace")); + + CreateNamespaceResponse createResponse = namespace.createNamespace(createRequest); + assertThat(createResponse).isNotNull(); + + // Describe namespace + DescribeNamespaceRequest describeRequest = new DescribeNamespaceRequest(); + describeRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + + DescribeNamespaceResponse describeResponse = namespace.describeNamespace(describeRequest); + assertThat(describeResponse).isNotNull(); + + // Check namespace exists + NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); + existsRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.namespaceExists(existsRequest); + + // List namespaces + ListNamespacesRequest listRequest = new ListNamespacesRequest(); + listRequest.setId(Collections.singletonList(TEST_WAREHOUSE)); + ListNamespacesResponse listResponse = namespace.listNamespaces(listRequest); + assertThat(listResponse.getNamespaces()).contains(TEST_WAREHOUSE + "." + testNamespace); + + // Drop namespace + DropNamespaceRequest dropRequest = new DropNamespaceRequest(); + dropRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.dropNamespace(dropRequest); + + // Verify namespace doesn't exist + assertThatThrownBy(() -> namespace.namespaceExists(existsRequest)) + .isInstanceOf(LanceNamespaceException.class) + .hasMessageContaining("not found"); + } + + @Test + public void testTableOperations() { + // Create namespace first + CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); + nsRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.createNamespace(nsRequest); + + String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8); + + // Create empty table + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); + createRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + createRequest.setLocation("s3://warehouse/" + testNamespace + "/" + tableName); + + CreateEmptyTableResponse createResponse = namespace.createEmptyTable(createRequest); + assertThat(createResponse.getLocation()).isNotNull(); + + // Describe table + DescribeTableRequest describeRequest = new DescribeTableRequest(); + describeRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + + DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); + assertThat(describeResponse.getLocation()).isNotNull(); + + // Check table exists + TableExistsRequest existsRequest = new TableExistsRequest(); + existsRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + namespace.tableExists(existsRequest); + + // List tables + ListTablesRequest listRequest = new ListTablesRequest(); + listRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + + ListTablesResponse listResponse = namespace.listTables(listRequest); + assertThat(listResponse.getTables()).contains(tableName); + + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + namespace.deregisterTable(deregisterRequest); + + // Verify table doesn't exist + assertThatThrownBy(() -> namespace.tableExists(existsRequest)) + .isInstanceOf(LanceNamespaceException.class) + .hasMessageContaining("not found"); + } + + @Test + public void testCreateEmptyTableWithLocation() { + // Create namespace first + CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); + nsRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.createNamespace(nsRequest); + + String tableName = "lance_table"; + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); + createRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + createRequest.setLocation("s3://warehouse/" + testNamespace + "/" + tableName); + + CreateEmptyTableResponse response = namespace.createEmptyTable(createRequest); + assertThat(response.getLocation()).isNotNull(); + + // Clean up table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, tableName)); + namespace.deregisterTable(deregisterRequest); + } + + @Test + public void testNestedNamespace() { + String nestedNs = "nested_" + UUID.randomUUID().toString().substring(0, 8); + + // Create parent namespace + CreateNamespaceRequest parentRequest = new CreateNamespaceRequest(); + parentRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + namespace.createNamespace(parentRequest); + + // Create nested namespace + CreateNamespaceRequest nestedRequest = new CreateNamespaceRequest(); + nestedRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, nestedNs)); + nestedRequest.setProperties(Collections.singletonMap("description", "Nested namespace")); + namespace.createNamespace(nestedRequest); + + // List nested namespaces + ListNamespacesRequest listRequest = new ListNamespacesRequest(); + listRequest.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace)); + ListNamespacesResponse listResponse = namespace.listNamespaces(listRequest); + assertThat(listResponse.getNamespaces()) + .contains(TEST_WAREHOUSE + "." + testNamespace + "." + nestedNs); + + // Drop nested namespace first + DropNamespaceRequest dropNested = new DropNamespaceRequest(); + dropNested.setId(Arrays.asList(TEST_WAREHOUSE, testNamespace, nestedNs)); + namespace.dropNamespace(dropNested); + } +} diff --git a/python/Makefile b/python/Makefile index e2255be..cab32ca 100644 --- a/python/Makefile +++ b/python/Makefile @@ -156,3 +156,7 @@ integ-test-polaris: .PHONY: integ-test-unity integ-test-unity: uv run pytest tests/test_unity_integration.py -v + +.PHONY: integ-test-iceberg +integ-test-iceberg: + uv run pytest tests/test_iceberg_integration.py -v diff --git a/python/src/lance_namespace_impls/iceberg.py b/python/src/lance_namespace_impls/iceberg.py index a9b81bf..fac64d0 100644 --- a/python/src/lance_namespace_impls/iceberg.py +++ b/python/src/lance_namespace_impls/iceberg.py @@ -1,5 +1,9 @@ """ Iceberg REST Catalog namespace implementation for Lance. + +The prefix (typically a warehouse or catalog name) is treated as part of the +namespace identifier, similar to how Polaris handles catalog names. +For example: [warehouse_name, namespace1, namespace2, ..., table_name] """ import logging @@ -51,7 +55,6 @@ class IcebergNamespaceConfig: ENDPOINT = "iceberg.endpoint" WAREHOUSE = "iceberg.warehouse" - PREFIX = "iceberg.prefix" AUTH_TOKEN = "iceberg.auth_token" CREDENTIAL = "iceberg.credential" CONNECT_TIMEOUT = "iceberg.connect_timeout_millis" @@ -61,7 +64,6 @@ class IcebergNamespaceConfig: endpoint: str warehouse: Optional[str] = None - prefix: str = "" auth_token: Optional[str] = None credential: Optional[str] = None connect_timeout: int = 10000 @@ -75,7 +77,6 @@ def __init__(self, properties: Dict[str, str]): raise ValueError(f"Required property {self.ENDPOINT} is not set") self.warehouse = properties.get(self.WAREHOUSE) - self.prefix = properties.get(self.PREFIX, "") self.auth_token = properties.get(self.AUTH_TOKEN) self.credential = properties.get(self.CREDENTIAL) self.connect_timeout = int(properties.get(self.CONNECT_TIMEOUT, "10000")) @@ -83,12 +84,9 @@ def __init__(self, properties: Dict[str, str]): self.max_retries = int(properties.get(self.MAX_RETRIES, "3")) self.root = properties.get(self.ROOT, "/tmp/lance") - def get_full_api_url(self) -> str: - """Get the full API URL with prefix.""" - base = self.endpoint.rstrip("/") - if self.prefix: - return f"{base}/{self.prefix}" - return base + def get_base_api_url(self) -> str: + """Get the base API URL without prefix.""" + return self.endpoint.rstrip("/") def create_dummy_schema() -> Dict[str, Any]: @@ -101,7 +99,15 @@ def create_dummy_schema() -> Dict[str, Any]: class IcebergNamespace(LanceNamespace): - """Iceberg REST Catalog namespace implementation for Lance.""" + """ + Iceberg REST Catalog namespace implementation for Lance. + + The prefix (warehouse) is included in the namespace identifier: + - Namespace ID format: [prefix, namespace1, namespace2, ...] + - Table ID format: [prefix, namespace1, namespace2, ..., table_name] + + This is consistent with how Polaris handles catalog names. + """ TABLE_TYPE_LANCE = "lance" TABLE_TYPE_KEY = "table_type" @@ -109,6 +115,7 @@ class IcebergNamespace(LanceNamespace): def __init__(self, **properties): """Initialize Iceberg namespace with configuration properties.""" self.config = IcebergNamespaceConfig(properties) + self._prefix_cache: Dict[str, str] = {} headers = {} if self.config.auth_token: @@ -117,7 +124,7 @@ def __init__(self, **properties): headers["X-Iceberg-Access-Delegation"] = "vended-credentials" self.rest_client = RestClient( - base_url=self.config.get_full_api_url(), + base_url=self.config.get_base_api_url(), headers=headers, connect_timeout=self.config.connect_timeout, read_timeout=self.config.read_timeout, @@ -138,27 +145,72 @@ def _encode_namespace(self, namespace: List[str]) -> str: joined = NAMESPACE_SEPARATOR.join(encoded_parts) return urllib.parse.quote(joined, safe="") + def _resolve_prefix(self, warehouse: str) -> str: + """Resolve warehouse name to actual API prefix. + + Some Iceberg REST catalogs (like Lakekeeper) use a different prefix + (e.g., warehouse UUID) than the warehouse name. This method calls + the config endpoint to get the actual prefix. + """ + if warehouse in self._prefix_cache: + return self._prefix_cache[warehouse] + + try: + response = self.rest_client.get( + "/v1/config", params={"warehouse": warehouse} + ) + if response and "defaults" in response: + prefix = response["defaults"].get("prefix") + if prefix: + self._prefix_cache[warehouse] = prefix + logger.debug( + f"Resolved warehouse '{warehouse}' to prefix '{prefix}'" + ) + return prefix + except Exception as e: + logger.debug(f"Failed to resolve prefix for warehouse '{warehouse}': {e}") + + self._prefix_cache[warehouse] = warehouse + return warehouse + + def _get_prefix_path(self, warehouse: str) -> str: + """Get the API path with prefix.""" + prefix = self._resolve_prefix(warehouse) + return f"/v1/{prefix}" + def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesResponse: - """List namespaces.""" + """List namespaces. + + The first element of request.id is treated as the prefix (warehouse). + Remaining elements specify the parent namespace to list children of. + """ ns_id = self._parse_identifier(request.id) + if not ns_id: + raise InvalidInputException("Must specify at least the prefix (warehouse)") + try: + prefix = ns_id[0] + parent_ns = ns_id[1:] if len(ns_id) > 1 else [] + prefix_path = self._get_prefix_path(prefix) + params = {} - if ns_id: - parent = self._encode_namespace(ns_id) + if parent_ns: + parent = self._encode_namespace(parent_ns) params["parent"] = parent if request.page_token: params["pageToken"] = request.page_token response = self.rest_client.get( - "/namespaces", params=params if params else None + f"{prefix_path}/namespaces", params=params if params else None ) namespaces = [] if response and "namespaces" in response: for ns in response["namespaces"]: if ns: - namespaces.append(ns[-1]) + full_ns = [prefix] + list(ns) + namespaces.append(".".join(full_ns)) namespaces = sorted(set(namespaces)) @@ -166,27 +218,41 @@ def list_namespaces(self, request: ListNamespacesRequest) -> ListNamespacesRespo except RestClientException as e: raise InternalException(f"Failed to list namespaces: {e}") + except InvalidInputException: + raise except Exception as e: raise InternalException(f"Failed to list namespaces: {e}") def create_namespace( self, request: CreateNamespaceRequest ) -> CreateNamespaceResponse: - """Create a new namespace.""" + """Create a new namespace. + + The first element of request.id is treated as the prefix (warehouse). + Remaining elements are the namespace to create. + """ ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least prefix and namespace levels" + ) try: + prefix = ns_id[0] + namespace = ns_id[1:] + prefix_path = self._get_prefix_path(prefix) + create_request = { - "namespace": ns_id, + "namespace": namespace, "properties": request.properties or {}, } - response = self.rest_client.post("/namespaces", create_request) + response = self.rest_client.post( + f"{prefix_path}/namespaces", create_request + ) - logger.info(f"Created namespace: {'.'.join(ns_id)}") + logger.info(f"Created namespace: {prefix}.{'.'.join(namespace)}") properties = response.get("properties") if response else {} return CreateNamespaceResponse(properties=properties) @@ -205,15 +271,27 @@ def create_namespace( def describe_namespace( self, request: DescribeNamespaceRequest ) -> DescribeNamespaceResponse: - """Describe a namespace.""" + """Describe a namespace. + + The first element of request.id is treated as the prefix (warehouse). + Remaining elements are the namespace to describe. + """ ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least prefix and namespace levels" + ) try: - namespace_path = self._encode_namespace(ns_id) - response = self.rest_client.get(f"/namespaces/{namespace_path}") + prefix = ns_id[0] + namespace = ns_id[1:] + prefix_path = self._get_prefix_path(prefix) + namespace_path = self._encode_namespace(namespace) + + response = self.rest_client.get( + f"{prefix_path}/namespaces/{namespace_path}" + ) properties = response.get("properties") if response else {} return DescribeNamespaceResponse(properties=properties) @@ -236,17 +314,27 @@ def namespace_exists(self, request: NamespaceExistsRequest) -> None: self.describe_namespace(describe_request) def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: - """Drop a namespace.""" + """Drop a namespace. + + The first element of request.id is treated as the prefix (warehouse). + Remaining elements are the namespace to drop. + """ ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException( + "Namespace must have at least prefix and namespace levels" + ) try: - namespace_path = self._encode_namespace(ns_id) - self.rest_client.delete(f"/namespaces/{namespace_path}") + prefix = ns_id[0] + namespace = ns_id[1:] + prefix_path = self._get_prefix_path(prefix) + namespace_path = self._encode_namespace(namespace) + + self.rest_client.delete(f"{prefix_path}/namespaces/{namespace_path}") - logger.info(f"Dropped namespace: {'.'.join(ns_id)}") + logger.info(f"Dropped namespace: {prefix}.{'.'.join(namespace)}") return DropNamespaceResponse(properties={}) @@ -262,20 +350,28 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse raise InternalException(f"Failed to drop namespace: {e}") def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: - """List tables in a namespace.""" + """List tables in a namespace. + + The first element of request.id is treated as the prefix (warehouse). + Remaining elements are the namespace to list tables from. + """ ns_id = self._parse_identifier(request.id) - if not ns_id: - raise InvalidInputException("Namespace must have at least one level") + if len(ns_id) < 2: + raise InvalidInputException("Must specify at least prefix and namespace") try: - namespace_path = self._encode_namespace(ns_id) + prefix = ns_id[0] + namespace = ns_id[1:] + prefix_path = self._get_prefix_path(prefix) + namespace_path = self._encode_namespace(namespace) + params = {} if request.page_token: params["pageToken"] = request.page_token response = self.rest_client.get( - f"/namespaces/{namespace_path}/tables", + f"{prefix_path}/namespaces/{namespace_path}/tables", params=params if params else None, ) @@ -283,7 +379,9 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: if response and "identifiers" in response: for table_id in response["identifiers"]: table_name = table_id.get("name") - if table_name and self._is_lance_table(ns_id, table_name): + if table_name and self._is_lance_table( + prefix, namespace, table_name + ): tables.append(table_name) tables = sorted(set(tables)) @@ -304,21 +402,30 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: def create_empty_table( self, request: CreateEmptyTableRequest ) -> CreateEmptyTableResponse: - """Create an empty table (metadata only operation).""" + """Create an empty table (metadata only operation). + + The first element of request.id is treated as the prefix (warehouse). + Middle elements are the namespace, last element is the table name. + """ table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have prefix, namespace, and table name" ) - namespace = table_id[:-1] + prefix = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: + prefix_path = self._get_prefix_path(prefix) + table_path = request.location if not table_path: - table_path = f"{self.config.root}/{'/'.join(namespace)}/{table_name}" + table_path = ( + f"{self.config.root}/{'/'.join(table_id[:-1])}/{table_name}" + ) properties = {self.TABLE_TYPE_KEY: self.TABLE_TYPE_LANCE} @@ -331,7 +438,7 @@ def create_empty_table( namespace_path = self._encode_namespace(namespace) self.rest_client.post( - f"/namespaces/{namespace_path}/tables", create_request + f"{prefix_path}/namespaces/{namespace_path}/tables", create_request ) logger.info(f"Created table: {'.'.join(table_id)}") @@ -345,7 +452,7 @@ def create_empty_table( ) if e.is_not_found(): raise NamespaceNotFoundException( - f"Namespace not found: {'.'.join(namespace)}" + f"Namespace not found: {prefix}.{'.'.join(namespace)}" ) raise InternalException(f"Failed to create empty table: {e}") except ( @@ -358,23 +465,29 @@ def create_empty_table( raise InternalException(f"Failed to create empty table: {e}") def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: - """Describe a table.""" + """Describe a table. + + The first element of request.id is treated as the prefix (warehouse). + Middle elements are the namespace, last element is the table name. + """ table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have prefix, namespace, and table name" ) - namespace = table_id[:-1] + prefix = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: + prefix_path = self._get_prefix_path(prefix) namespace_path = self._encode_namespace(namespace) encoded_table_name = urllib.parse.quote(table_name, safe="") response = self.rest_client.get( - f"/namespaces/{namespace_path}/tables/{encoded_table_name}" + f"{prefix_path}/namespaces/{namespace_path}/tables/{encoded_table_name}" ) if not response or "metadata" not in response: @@ -413,23 +526,29 @@ def table_exists(self, request: TableExistsRequest) -> None: def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: - """Deregister a table (remove from catalog without deleting data).""" + """Deregister a table (remove from catalog without deleting data). + + The first element of request.id is treated as the prefix (warehouse). + Middle elements are the namespace, last element is the table name. + """ table_id = self._parse_identifier(request.id) - if len(table_id) < 2: + if len(table_id) < 3: raise InvalidInputException( - "Table identifier must have at least namespace and table name" + "Table identifier must have prefix, namespace, and table name" ) - namespace = table_id[:-1] + prefix = table_id[0] + namespace = table_id[1:-1] table_name = table_id[-1] try: + prefix_path = self._get_prefix_path(prefix) namespace_path = self._encode_namespace(namespace) encoded_table_name = urllib.parse.quote(table_name, safe="") response = self.rest_client.get( - f"/namespaces/{namespace_path}/tables/{encoded_table_name}" + f"{prefix_path}/namespaces/{namespace_path}/tables/{encoded_table_name}" ) table_location = None @@ -437,7 +556,7 @@ def deregister_table( table_location = response["metadata"].get("location") self.rest_client.delete( - f"/namespaces/{namespace_path}/tables/{encoded_table_name}", + f"{prefix_path}/namespaces/{namespace_path}/tables/{encoded_table_name}", params={"purgeRequested": "false"}, ) @@ -463,14 +582,17 @@ def _parse_identifier(self, identifier: List[str]) -> List[str]: """Parse identifier list.""" return identifier if identifier else [] - def _is_lance_table(self, namespace: List[str], table_name: str) -> bool: + def _is_lance_table( + self, prefix: str, namespace: List[str], table_name: str + ) -> bool: """Check if a table is a Lance table.""" try: + prefix_path = self._get_prefix_path(prefix) namespace_path = self._encode_namespace(namespace) encoded_table_name = urllib.parse.quote(table_name, safe="") response = self.rest_client.get( - f"/namespaces/{namespace_path}/tables/{encoded_table_name}" + f"{prefix_path}/namespaces/{namespace_path}/tables/{encoded_table_name}" ) if response and "metadata" in response: diff --git a/python/tests/test_iceberg_integration.py b/python/tests/test_iceberg_integration.py new file mode 100644 index 0000000..bda8eac --- /dev/null +++ b/python/tests/test_iceberg_integration.py @@ -0,0 +1,223 @@ +""" +Integration tests for Iceberg REST Catalog namespace implementation. + +This test uses Lakekeeper as the Iceberg REST Catalog implementation. +To run these tests, start the catalog with: + cd docker/lakekeeper && docker-compose up -d + +Tests are automatically skipped if the catalog is not available. +""" + +import os +import uuid +import urllib.request +import urllib.error +import unittest + +import pytest + +from lance_namespace_impls.iceberg import IcebergNamespace +from lance_namespace_impls.rest_client import ( + NamespaceNotFoundException, + TableNotFoundException, +) +from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + CreateNamespaceRequest, + DeregisterTableRequest, + DescribeNamespaceRequest, + DescribeTableRequest, + DropNamespaceRequest, + ListNamespacesRequest, + ListTablesRequest, + NamespaceExistsRequest, + TableExistsRequest, +) + + +ICEBERG_ENDPOINT = os.environ.get("ICEBERG_ENDPOINT", "http://localhost:8282/catalog") +ICEBERG_WAREHOUSE = os.environ.get("ICEBERG_WAREHOUSE", "test_warehouse") + + +def check_iceberg_available(): + """Check if Iceberg REST Catalog is available.""" + try: + url = f"{ICEBERG_ENDPOINT}/v1/config?warehouse={ICEBERG_WAREHOUSE}" + req = urllib.request.Request(url, method="GET") + try: + with urllib.request.urlopen(req, timeout=5) as response: + return response.status == 200 + except urllib.error.HTTPError: + return False + except Exception: + return False + + +iceberg_available = check_iceberg_available() + + +@pytest.mark.integration +@unittest.skipUnless( + iceberg_available, f"Iceberg REST Catalog is not available at {ICEBERG_ENDPOINT}" +) +class TestIcebergNamespaceIntegration(unittest.TestCase): + """Integration tests for IcebergNamespace against a running Iceberg REST Catalog.""" + + def setUp(self): + """Set up test fixtures.""" + unique_id = uuid.uuid4().hex[:8] + self.test_warehouse = ICEBERG_WAREHOUSE + self.test_namespace = f"test_ns_{unique_id}" + + properties = { + "iceberg.endpoint": ICEBERG_ENDPOINT, + "iceberg.root": "s3://warehouse", + } + + self.namespace = IcebergNamespace(**properties) + + def tearDown(self): + """Clean up test resources.""" + try: + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.drop_namespace(drop_request) + except Exception: + pass + + if self.namespace: + self.namespace.close() + + def test_namespace_operations(self): + """Test namespace CRUD operations.""" + # Create namespace + create_request = CreateNamespaceRequest() + create_request.id = [self.test_warehouse, self.test_namespace] + create_request.properties = {"description": "Test namespace"} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + # Describe namespace + describe_request = DescribeNamespaceRequest() + describe_request.id = [self.test_warehouse, self.test_namespace] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + + # Check namespace exists + exists_request = NamespaceExistsRequest() + exists_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.namespace_exists(exists_request) + + # List namespaces + list_request = ListNamespacesRequest() + list_request.id = [self.test_warehouse] + list_response = self.namespace.list_namespaces(list_request) + full_ns_name = f"{self.test_warehouse}.{self.test_namespace}" + self.assertIn(full_ns_name, list_response.namespaces) + + # Drop namespace + drop_request = DropNamespaceRequest() + drop_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.drop_namespace(drop_request) + + # Verify namespace doesn't exist + with self.assertRaises(NamespaceNotFoundException): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.create_namespace(ns_request) + + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + + # Create empty table + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_warehouse, self.test_namespace, table_name] + create_request.location = f"s3://warehouse/{self.test_namespace}/{table_name}" + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + + # Describe table + describe_request = DescribeTableRequest() + describe_request.id = [self.test_warehouse, self.test_namespace, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + + # Check table exists + exists_request = TableExistsRequest() + exists_request.id = [self.test_warehouse, self.test_namespace, table_name] + self.namespace.table_exists(exists_request) + + # List tables + list_request = ListTablesRequest() + list_request.id = [self.test_warehouse, self.test_namespace] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + # Deregister table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_warehouse, self.test_namespace, table_name] + self.namespace.deregister_table(deregister_request) + + # Verify table doesn't exist + with self.assertRaises(TableNotFoundException): + self.namespace.table_exists(exists_request) + + def test_create_empty_table_with_location(self): + """Test creating an empty table with a specific location.""" + # Create namespace first + ns_request = CreateNamespaceRequest() + ns_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.create_namespace(ns_request) + + table_name = "lance_table" + create_request = CreateEmptyTableRequest() + create_request.id = [self.test_warehouse, self.test_namespace, table_name] + create_request.location = f"s3://warehouse/{self.test_namespace}/{table_name}" + + response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(response.location) + + # Clean up table + deregister_request = DeregisterTableRequest() + deregister_request.id = [self.test_warehouse, self.test_namespace, table_name] + self.namespace.deregister_table(deregister_request) + + def test_nested_namespace(self): + """Test nested namespace operations.""" + nested_ns = f"nested_{uuid.uuid4().hex[:8]}" + + # Create parent namespace + parent_request = CreateNamespaceRequest() + parent_request.id = [self.test_warehouse, self.test_namespace] + self.namespace.create_namespace(parent_request) + + # Create nested namespace + nested_request = CreateNamespaceRequest() + nested_request.id = [self.test_warehouse, self.test_namespace, nested_ns] + nested_request.properties = {"description": "Nested namespace"} + self.namespace.create_namespace(nested_request) + + # List nested namespaces + list_request = ListNamespacesRequest() + list_request.id = [self.test_warehouse, self.test_namespace] + list_response = self.namespace.list_namespaces(list_request) + expected_ns = f"{self.test_warehouse}.{self.test_namespace}.{nested_ns}" + self.assertIn(expected_ns, list_response.namespaces) + + # Drop nested namespace first + drop_nested = DropNamespaceRequest() + drop_nested.id = [self.test_warehouse, self.test_namespace, nested_ns] + self.namespace.drop_namespace(drop_nested) + + +if __name__ == "__main__": + unittest.main() From f9e51b39ceaf5005bb9105a586b5d9475cbdab60 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 22:35:19 -0800 Subject: [PATCH 08/20] commit --- java/Makefile | 2 +- python/Makefile | 4 +- python/tests/test_iceberg.py | 540 +++++++++++++++++++++++++++++++++++ 3 files changed, 543 insertions(+), 3 deletions(-) create mode 100644 python/tests/test_iceberg.py diff --git a/java/Makefile b/java/Makefile index 4500848..2cb13c3 100644 --- a/java/Makefile +++ b/java/Makefile @@ -159,4 +159,4 @@ integ-test-iceberg: .PHONY: integ-test-unity integ-test-unity: - ./mvnw test -pl lance-namespace-unity -Dtest="*IntegrationTest" -DfailIfNoTests=false + ./mvnw test -pl lance-namespace-unity -Dtest="*Integration" -DfailIfNoTests=false diff --git a/python/Makefile b/python/Makefile index cab32ca..e649163 100644 --- a/python/Makefile +++ b/python/Makefile @@ -67,8 +67,8 @@ test-unity: .PHONY: lint-iceberg lint-iceberg: - uv run ruff check src/lance_namespace_impls/iceberg.py - uv run ruff format --check src/lance_namespace_impls/iceberg.py + uv run ruff check src/lance_namespace_impls/iceberg.py tests/test_iceberg.py tests/test_iceberg_integration.py + uv run ruff format --check src/lance_namespace_impls/iceberg.py tests/test_iceberg.py tests/test_iceberg_integration.py .PHONY: install-iceberg install-iceberg: diff --git a/python/tests/test_iceberg.py b/python/tests/test_iceberg.py new file mode 100644 index 0000000..27a28ac --- /dev/null +++ b/python/tests/test_iceberg.py @@ -0,0 +1,540 @@ +""" +Tests for Iceberg REST Catalog namespace implementation. +""" + +import unittest +from unittest.mock import MagicMock, patch + +from lance_namespace_impls.iceberg import ( + IcebergNamespace, + IcebergNamespaceConfig, + create_dummy_schema, +) +from lance_namespace_impls.rest_client import ( + RestClientException, + NamespaceNotFoundException, + NamespaceAlreadyExistsException, + TableNotFoundException, + TableAlreadyExistsException, + InvalidInputException, +) +from lance_namespace_urllib3_client.models import ( + ListNamespacesRequest, + CreateNamespaceRequest, + DescribeNamespaceRequest, + DropNamespaceRequest, + ListTablesRequest, + CreateEmptyTableRequest, + DescribeTableRequest, + DeregisterTableRequest, +) + + +class TestIcebergNamespaceConfig(unittest.TestCase): + """Test Iceberg namespace configuration.""" + + def test_config_initialization(self): + """Test configuration initialization with required properties.""" + properties = { + "iceberg.endpoint": "https://iceberg.example.com", + "iceberg.root": "/data/lance", + "iceberg.auth_token": "test_token", + "iceberg.warehouse": "test_warehouse", + } + + config = IcebergNamespaceConfig(properties) + + self.assertEqual(config.endpoint, "https://iceberg.example.com") + self.assertEqual(config.root, "/data/lance") + self.assertEqual(config.auth_token, "test_token") + self.assertEqual(config.warehouse, "test_warehouse") + + def test_config_defaults(self): + """Test configuration with default values.""" + properties = {"iceberg.endpoint": "https://iceberg.example.com"} + + config = IcebergNamespaceConfig(properties) + + self.assertEqual(config.root, "/tmp/lance") + self.assertIsNone(config.auth_token) + self.assertIsNone(config.warehouse) + self.assertEqual(config.connect_timeout, 10000) + self.assertEqual(config.read_timeout, 30000) + self.assertEqual(config.max_retries, 3) + + def test_config_missing_endpoint(self): + """Test configuration fails without endpoint.""" + properties = {} + + with self.assertRaises(ValueError) as context: + IcebergNamespaceConfig(properties) + + self.assertIn("iceberg.endpoint", str(context.exception)) + + def test_get_base_api_url(self): + """Test API URL generation.""" + properties = {"iceberg.endpoint": "https://iceberg.example.com/"} + config = IcebergNamespaceConfig(properties) + + self.assertEqual(config.get_base_api_url(), "https://iceberg.example.com") + + +class TestIcebergNamespace(unittest.TestCase): + """Test Iceberg namespace implementation.""" + + def setUp(self): + """Set up test fixtures.""" + self.properties = { + "iceberg.endpoint": "https://iceberg.example.com", + "iceberg.root": "/data/lance", + } + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_namespace_id(self, mock_rest_client_class): + """Test namespace ID generation.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + ns_id = namespace.namespace_id() + + self.assertIn("IcebergNamespace", ns_id) + self.assertIn("iceberg.example.com", ns_id) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_list_namespaces_prefix_level(self, mock_rest_client_class): + """Test listing namespaces at prefix level.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + {"namespaces": [["ns1"], ["ns2"], ["ns3"]]}, + ] + + namespace = IcebergNamespace(**self.properties) + + request = ListNamespacesRequest() + request.id = ["warehouse1"] + + response = namespace.list_namespaces(request) + + self.assertEqual( + sorted(response.namespaces), + ["warehouse1.ns1", "warehouse1.ns2", "warehouse1.ns3"], + ) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_list_namespaces_nested(self, mock_rest_client_class): + """Test listing nested namespaces.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + {"namespaces": [["parent", "child1"], ["parent", "child2"]]}, + ] + + namespace = IcebergNamespace(**self.properties) + + request = ListNamespacesRequest() + request.id = ["warehouse1", "parent"] + + response = namespace.list_namespaces(request) + + self.assertEqual( + sorted(response.namespaces), + ["warehouse1.parent.child1", "warehouse1.parent.child2"], + ) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_list_namespaces_empty_id(self, mock_rest_client_class): + """Test listing namespaces without prefix fails.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + + request = ListNamespacesRequest() + request.id = [] + + with self.assertRaises(InvalidInputException): + namespace.list_namespaces(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_namespace(self, mock_rest_client_class): + """Test creating a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.post.return_value = {"properties": {"key": "value"}} + + namespace = IcebergNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = ["warehouse1", "test_namespace"] + request.properties = {"key": "value"} + + response = namespace.create_namespace(request) + + self.assertEqual(response.properties, {"key": "value"}) + mock_client.post.assert_called_once_with( + "/v1/warehouse1/namespaces", + {"namespace": ["test_namespace"], "properties": {"key": "value"}}, + ) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_namespace_already_exists(self, mock_rest_client_class): + """Test creating a namespace that already exists.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.post.side_effect = RestClientException( + status_code=409, response_body="Conflict" + ) + + namespace = IcebergNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = ["warehouse1", "existing_namespace"] + + with self.assertRaises(NamespaceAlreadyExistsException): + namespace.create_namespace(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_namespace_invalid_id(self, mock_rest_client_class): + """Test creating namespace with invalid ID fails.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + + request = CreateNamespaceRequest() + request.id = ["only_prefix"] + + with self.assertRaises(InvalidInputException): + namespace.create_namespace(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_describe_namespace(self, mock_rest_client_class): + """Test describing a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + {"properties": {"key": "value"}}, + ] + + namespace = IcebergNamespace(**self.properties) + + request = DescribeNamespaceRequest() + request.id = ["warehouse1", "test_namespace"] + + response = namespace.describe_namespace(request) + + self.assertEqual(response.properties, {"key": "value"}) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_describe_namespace_not_found(self, mock_rest_client_class): + """Test describing a namespace that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + RestClientException(status_code=404, response_body="Not found"), + ] + + namespace = IcebergNamespace(**self.properties) + + request = DescribeNamespaceRequest() + request.id = ["warehouse1", "nonexistent"] + + with self.assertRaises(NamespaceNotFoundException): + namespace.describe_namespace(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_drop_namespace(self, mock_rest_client_class): + """Test dropping a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + + namespace = IcebergNamespace(**self.properties) + + request = DropNamespaceRequest() + request.id = ["warehouse1", "test_namespace"] + + response = namespace.drop_namespace(request) + + self.assertIsNotNone(response) + mock_client.delete.assert_called_once() + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_drop_namespace_not_found(self, mock_rest_client_class): + """Test dropping a namespace that doesn't exist returns success.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.delete.side_effect = RestClientException( + status_code=404, response_body="Not found" + ) + + namespace = IcebergNamespace(**self.properties) + + request = DropNamespaceRequest() + request.id = ["warehouse1", "nonexistent"] + + response = namespace.drop_namespace(request) + + self.assertIsNotNone(response) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_list_tables(self, mock_rest_client_class): + """Test listing tables in a namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + {"identifiers": [{"name": "table1"}, {"name": "table2"}]}, + {"metadata": {"properties": {"table_type": "lance"}}}, + {"metadata": {"properties": {"table_type": "lance"}}}, + ] + + namespace = IcebergNamespace(**self.properties) + + request = ListTablesRequest() + request.id = ["warehouse1", "test_namespace"] + + response = namespace.list_tables(request) + + self.assertEqual(sorted(response.tables), ["table1", "table2"]) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_list_tables_invalid_id(self, mock_rest_client_class): + """Test listing tables with invalid ID fails.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + + request = ListTablesRequest() + request.id = ["only_prefix"] + + with self.assertRaises(InvalidInputException): + namespace.list_tables(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_empty_table(self, mock_rest_client_class): + """Test creating an empty table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.post.return_value = {} + + namespace = IcebergNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["warehouse1", "test_namespace", "test_table"] + request.location = None + + response = namespace.create_empty_table(request) + + self.assertEqual( + response.location, "/data/lance/warehouse1/test_namespace/test_table" + ) + mock_client.post.assert_called_once() + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_empty_table_with_location(self, mock_rest_client_class): + """Test creating an empty table with custom location.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.post.return_value = {} + + namespace = IcebergNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["warehouse1", "test_namespace", "test_table"] + request.location = "/custom/path/test_table" + + response = namespace.create_empty_table(request) + + self.assertEqual(response.location, "/custom/path/test_table") + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_empty_table_already_exists(self, mock_rest_client_class): + """Test creating a table that already exists.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.return_value = {"defaults": {"prefix": "warehouse1"}} + mock_client.post.side_effect = RestClientException( + status_code=409, response_body="Conflict" + ) + + namespace = IcebergNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["warehouse1", "test_namespace", "existing_table"] + + with self.assertRaises(TableAlreadyExistsException): + namespace.create_empty_table(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_create_empty_table_invalid_id(self, mock_rest_client_class): + """Test creating table with invalid ID fails.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + + request = CreateEmptyTableRequest() + request.id = ["warehouse1", "only_namespace"] + + with self.assertRaises(InvalidInputException): + namespace.create_empty_table(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_describe_table(self, mock_rest_client_class): + """Test describing a table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + { + "metadata": { + "location": "/data/lance/ns/table", + "properties": {"table_type": "lance", "key": "value"}, + } + }, + ] + + namespace = IcebergNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["warehouse1", "test_namespace", "test_table"] + + response = namespace.describe_table(request) + + self.assertEqual(response.location, "/data/lance/ns/table") + self.assertEqual( + response.storage_options, {"table_type": "lance", "key": "value"} + ) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_describe_table_not_lance(self, mock_rest_client_class): + """Test describing a table that is not a Lance table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + { + "metadata": { + "location": "/data/iceberg/ns/table", + "properties": {"table_type": "iceberg"}, + } + }, + ] + + namespace = IcebergNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["warehouse1", "test_namespace", "test_table"] + + with self.assertRaises(InvalidInputException): + namespace.describe_table(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_describe_table_not_found(self, mock_rest_client_class): + """Test describing a table that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + RestClientException(status_code=404, response_body="Not found"), + ] + + namespace = IcebergNamespace(**self.properties) + + request = DescribeTableRequest() + request.id = ["warehouse1", "test_namespace", "nonexistent"] + + with self.assertRaises(TableNotFoundException): + namespace.describe_table(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_deregister_table(self, mock_rest_client_class): + """Test deregistering a table.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + {"metadata": {"location": "/data/lance/ns/table"}}, + ] + + namespace = IcebergNamespace(**self.properties) + + request = DeregisterTableRequest() + request.id = ["warehouse1", "test_namespace", "test_table"] + + response = namespace.deregister_table(request) + + self.assertEqual(response.location, "/data/lance/ns/table") + mock_client.delete.assert_called_once() + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_deregister_table_not_found(self, mock_rest_client_class): + """Test deregistering a table that doesn't exist.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + mock_client.get.side_effect = [ + {"defaults": {"prefix": "warehouse1"}}, + RestClientException(status_code=404, response_body="Not found"), + ] + + namespace = IcebergNamespace(**self.properties) + + request = DeregisterTableRequest() + request.id = ["warehouse1", "test_namespace", "nonexistent"] + + with self.assertRaises(TableNotFoundException): + namespace.deregister_table(request) + + @patch("lance_namespace_impls.iceberg.RestClient") + def test_close(self, mock_rest_client_class): + """Test closing the namespace.""" + mock_client = MagicMock() + mock_rest_client_class.return_value = mock_client + + namespace = IcebergNamespace(**self.properties) + namespace.close() + + mock_client.close.assert_called_once() + + def test_create_dummy_schema(self): + """Test dummy schema creation.""" + schema = create_dummy_schema() + + self.assertEqual(schema["type"], "struct") + self.assertEqual(schema["schema-id"], 0) + self.assertEqual(len(schema["fields"]), 1) + self.assertEqual(schema["fields"][0]["name"], "dummy") + + +if __name__ == "__main__": + unittest.main() From b59d5f83d07a0492e0a4e280ae7927130acf7ba2 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 30 Dec 2025 22:57:56 -0800 Subject: [PATCH 09/20] fix glue --- .github/workflows/java-integ-glue.yml | 72 ++++ .github/workflows/python-glue.yml | 2 + .github/workflows/python-integ-glue.yml | 78 +++++ Makefile | 8 + java/Makefile | 6 +- java/lance-namespace-glue/pom.xml | 14 + .../glue/TestGlueNamespaceIntegration.java | 320 ++++++++++++++++++ python/Makefile | 8 +- python/tests/test_glue_integration.py | 287 ++++++++++++++++ 9 files changed, 792 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/java-integ-glue.yml create mode 100644 .github/workflows/python-integ-glue.yml create mode 100644 java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java create mode 100644 python/tests/test_glue_integration.py diff --git a/.github/workflows/java-integ-glue.yml b/.github/workflows/java-integ-glue.yml new file mode 100644 index 0000000..20513d5 --- /dev/null +++ b/.github/workflows/java-integ-glue.yml @@ -0,0 +1,72 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Java Glue Integration + +on: + push: + branches: + - main + paths: + - java/lance-namespace-glue/** + - .github/workflows/java-integ-glue.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - java/lance-namespace-glue/** + - .github/workflows/java-integ-glue.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + # Only run if AWS credentials are available + if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} + steps: + - name: Check AWS credentials + id: check-creds + run: | + if [ -n "${{ secrets.AWS_ACCESS_KEY_ID }}" ] && [ -n "${{ secrets.AWS_SECRET_ACCESS_KEY }}" ]; then + echo "has_creds=true" >> $GITHUB_OUTPUT + else + echo "has_creds=false" >> $GITHUB_OUTPUT + echo "AWS credentials not configured - skipping integration tests" + fi + - name: Checkout + if: steps.check-creds.outputs.has_creds == 'true' + uses: actions/checkout@v4 + - name: Set up JDK 17 + if: steps.check-creds.outputs.has_creds == 'true' + uses: actions/setup-java@v4 + with: + java-version: "17" + distribution: "temurin" + cache: "maven" + - name: Build + if: steps.check-creds.outputs.has_creds == 'true' + run: make build-java + - name: Run integration tests + if: steps.check-creds.outputs.has_creds == 'true' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ secrets.AWS_REGION || 'us-east-1' }} + run: make java-integ-test-glue diff --git a/.github/workflows/python-glue.yml b/.github/workflows/python-glue.yml index 464ed66..2084e56 100644 --- a/.github/workflows/python-glue.yml +++ b/.github/workflows/python-glue.yml @@ -19,6 +19,7 @@ on: paths: - python/src/lance_namespace_impls/glue.py - python/tests/test_glue.py + - python/tests/test_glue_integration.py - python/pyproject.toml - .github/workflows/python-glue.yml pull_request: @@ -30,6 +31,7 @@ on: paths: - python/src/lance_namespace_impls/glue.py - python/tests/test_glue.py + - python/tests/test_glue_integration.py - python/pyproject.toml - .github/workflows/python-glue.yml diff --git a/.github/workflows/python-integ-glue.yml b/.github/workflows/python-integ-glue.yml new file mode 100644 index 0000000..6d429d9 --- /dev/null +++ b/.github/workflows/python-integ-glue.yml @@ -0,0 +1,78 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Python Glue Integration + +on: + push: + branches: + - main + paths: + - python/src/lance_namespace_impls/glue.py + - python/tests/test_glue.py + - python/tests/test_glue_integration.py + - .github/workflows/python-integ-glue.yml + pull_request: + types: + - opened + - synchronize + - ready_for_review + - reopened + paths: + - python/src/lance_namespace_impls/glue.py + - python/tests/test_glue.py + - python/tests/test_glue_integration.py + - .github/workflows/python-integ-glue.yml + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + integration-test: + runs-on: ubuntu-24.04 + timeout-minutes: 30 + # Only run if AWS credentials are available + if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} + steps: + - name: Check AWS credentials + id: check-creds + run: | + if [ -n "${{ secrets.AWS_ACCESS_KEY_ID }}" ] && [ -n "${{ secrets.AWS_SECRET_ACCESS_KEY }}" ]; then + echo "has_creds=true" >> $GITHUB_OUTPUT + else + echo "has_creds=false" >> $GITHUB_OUTPUT + echo "AWS credentials not configured - skipping integration tests" + fi + - name: Checkout + if: steps.check-creds.outputs.has_creds == 'true' + uses: actions/checkout@v4 + - name: Set up Python + if: steps.check-creds.outputs.has_creds == 'true' + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install uv + if: steps.check-creds.outputs.has_creds == 'true' + uses: astral-sh/setup-uv@v4 + - name: Install dependencies + if: steps.check-creds.outputs.has_creds == 'true' + working-directory: python + run: make install-glue + - name: Run integration tests + if: steps.check-creds.outputs.has_creds == 'true' + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ secrets.AWS_REGION || 'us-east-1' }} + run: make python-integ-test-glue diff --git a/Makefile b/Makefile index 5ec78e1..8081a95 100644 --- a/Makefile +++ b/Makefile @@ -152,6 +152,10 @@ java-integ-test-iceberg: java-integ-test-unity: cd java && make integ-test-unity +.PHONY: java-integ-test-glue +java-integ-test-glue: + cd java && make integ-test-glue + # ============================================================================ # Python Integration test targets # ============================================================================ @@ -183,3 +187,7 @@ python-integ-test-unity: .PHONY: python-integ-test-iceberg python-integ-test-iceberg: cd python && make integ-test-iceberg + +.PHONY: python-integ-test-glue +python-integ-test-glue: + cd python && make integ-test-glue diff --git a/java/Makefile b/java/Makefile index 2cb13c3..e1eea6e 100644 --- a/java/Makefile +++ b/java/Makefile @@ -25,7 +25,7 @@ build-glue: .PHONY: test-glue test-glue: - ./mvnw test -pl lance-namespace-glue + ./mvnw test -pl lance-namespace-glue -Dtest="!*Integration" # ============================================================================ # Hive2 @@ -160,3 +160,7 @@ integ-test-iceberg: .PHONY: integ-test-unity integ-test-unity: ./mvnw test -pl lance-namespace-unity -Dtest="*Integration" -DfailIfNoTests=false + +.PHONY: integ-test-glue +integ-test-glue: + ./mvnw test -pl lance-namespace-glue -Dtest="*Integration" -DfailIfNoTests=false diff --git a/java/lance-namespace-glue/pom.xml b/java/lance-namespace-glue/pom.xml index d3dffa8..cb8576c 100644 --- a/java/lance-namespace-glue/pom.xml +++ b/java/lance-namespace-glue/pom.xml @@ -75,6 +75,20 @@ 5.18.0 test + + + org.assertj + assertj-core + 3.26.3 + test + + + + software.amazon.awssdk + sts + ${aws.sdk.version} + test + diff --git a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java new file mode 100644 index 0000000..3143b1f --- /dev/null +++ b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java @@ -0,0 +1,320 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lance.namespace.glue; + +import org.lance.namespace.errors.LanceNamespaceException; +import org.lance.namespace.model.CreateEmptyTableRequest; +import org.lance.namespace.model.CreateEmptyTableResponse; +import org.lance.namespace.model.CreateNamespaceRequest; +import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; +import org.lance.namespace.model.DescribeNamespaceRequest; +import org.lance.namespace.model.DescribeNamespaceResponse; +import org.lance.namespace.model.DescribeTableRequest; +import org.lance.namespace.model.DescribeTableResponse; +import org.lance.namespace.model.DropNamespaceRequest; +import org.lance.namespace.model.ListNamespacesRequest; +import org.lance.namespace.model.ListNamespacesResponse; +import org.lance.namespace.model.ListTablesRequest; +import org.lance.namespace.model.ListTablesResponse; +import org.lance.namespace.model.NamespaceExistsRequest; +import org.lance.namespace.model.TableExistsRequest; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Integration tests for GlueNamespace against a real AWS Glue catalog. + * + *

To run these tests locally: + * + *

    + *
  1. Configure AWS credentials (via environment variables, ~/.aws/credentials, or IAM role) + *
  2. Run: make integ-test-glue + *
+ * + *

Tests are automatically skipped if AWS credentials are not available. + */ +public class TestGlueNamespaceIntegration { + + private static final String AWS_REGION = + System.getenv("AWS_REGION") != null ? System.getenv("AWS_REGION") : "us-east-1"; + private static boolean awsCredentialsAvailable = false; + private static Path tempDir; + + private GlueNamespace namespace; + private BufferAllocator allocator; + private String testDatabase; + private List createdDatabases; + + @BeforeAll + public static void checkAwsCredentialsAvailable() { + // Check if AWS credentials are available via environment variables + String accessKeyId = System.getenv("AWS_ACCESS_KEY_ID"); + String secretAccessKey = System.getenv("AWS_SECRET_ACCESS_KEY"); + + if (accessKeyId != null + && !accessKeyId.isEmpty() + && secretAccessKey != null + && !secretAccessKey.isEmpty()) { + awsCredentialsAvailable = true; + System.out.println("AWS credentials found in environment variables"); + } else { + // Try to use default credentials chain by making a simple API call + try { + software.amazon.awssdk.services.sts.StsClient stsClient = + software.amazon.awssdk.services.sts.StsClient.builder() + .region(software.amazon.awssdk.regions.Region.of(AWS_REGION)) + .build(); + stsClient.getCallerIdentity(); + stsClient.close(); + awsCredentialsAvailable = true; + System.out.println("AWS credentials found via default credentials chain"); + } catch (Exception e) { + awsCredentialsAvailable = false; + System.out.println( + "AWS credentials not available (" + e.getMessage() + ") - skipping integration tests"); + } + } + + if (awsCredentialsAvailable) { + try { + tempDir = Files.createTempDirectory("lance_glue_test_"); + System.out.println("Created temp directory: " + tempDir); + } catch (IOException e) { + System.out.println("Failed to create temp directory: " + e.getMessage()); + awsCredentialsAvailable = false; + } + } + } + + @BeforeEach + public void setUp() { + Assumptions.assumeTrue(awsCredentialsAvailable, "AWS credentials are not available"); + + allocator = new RootAllocator(); + namespace = new GlueNamespace(); + createdDatabases = new ArrayList<>(); + + String uniqueId = UUID.randomUUID().toString().substring(0, 8); + testDatabase = "lance_test_db_" + uniqueId; + + Map config = new HashMap<>(); + config.put("region", AWS_REGION); + config.put("root", tempDir.toString()); + + namespace.initialize(config, allocator); + } + + @AfterEach + public void tearDown() { + // Clean up test resources + for (String dbName : createdDatabases) { + try { + cleanupDatabase(dbName); + } catch (Exception e) { + // Ignore cleanup errors + } + } + + if (namespace != null) { + namespace.close(); + } + + if (allocator != null) { + allocator.close(); + } + } + + private void cleanupDatabase(String databaseName) { + try { + // First, delete all tables in the database + ListTablesRequest listRequest = new ListTablesRequest(); + listRequest.setId(Collections.singletonList(databaseName)); + ListTablesResponse listResponse = namespace.listTables(listRequest); + + for (String tableName : listResponse.getTables()) { + try { + DeregisterTableRequest deregRequest = new DeregisterTableRequest(); + deregRequest.setId(Arrays.asList(databaseName, tableName)); + namespace.deregisterTable(deregRequest); + } catch (Exception e) { + // Ignore + } + } + + // Then drop the database + DropNamespaceRequest dropRequest = new DropNamespaceRequest(); + dropRequest.setId(Collections.singletonList(databaseName)); + namespace.dropNamespace(dropRequest); + } catch (Exception e) { + // Ignore cleanup errors + } + } + + private String createTestDatabase(String suffix) { + String dbName = "lance_test_" + UUID.randomUUID().toString().substring(0, 8) + suffix; + createdDatabases.add(dbName); + + CreateNamespaceRequest createRequest = new CreateNamespaceRequest(); + createRequest.setId(Collections.singletonList(dbName)); + createRequest.setProperties( + Collections.singletonMap("description", "Lance integration test database")); + namespace.createNamespace(createRequest); + + return dbName; + } + + @Test + public void testNamespaceOperations() { + String dbName = "lance_test_" + UUID.randomUUID().toString().substring(0, 8); + createdDatabases.add(dbName); + + // Create namespace + CreateNamespaceRequest createRequest = new CreateNamespaceRequest(); + createRequest.setId(Collections.singletonList(dbName)); + createRequest.setProperties(Collections.singletonMap("description", "Test database for Lance")); + + CreateNamespaceResponse createResponse = namespace.createNamespace(createRequest); + assertThat(createResponse).isNotNull(); + + // Describe namespace + DescribeNamespaceRequest describeRequest = new DescribeNamespaceRequest(); + describeRequest.setId(Collections.singletonList(dbName)); + + DescribeNamespaceResponse describeResponse = namespace.describeNamespace(describeRequest); + assertThat(describeResponse).isNotNull(); + assertThat(describeResponse.getProperties()) + .containsEntry("description", "Test database for Lance"); + + // Check namespace exists + NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); + existsRequest.setId(Collections.singletonList(dbName)); + namespace.namespaceExists(existsRequest); // Should not throw + + // List namespaces + ListNamespacesRequest listRequest = new ListNamespacesRequest(); + listRequest.setId(Collections.emptyList()); + ListNamespacesResponse listResponse = namespace.listNamespaces(listRequest); + assertThat(listResponse.getNamespaces()).contains(dbName); + + // Drop namespace + DropNamespaceRequest dropRequest = new DropNamespaceRequest(); + dropRequest.setId(Collections.singletonList(dbName)); + namespace.dropNamespace(dropRequest); + createdDatabases.remove(dbName); + + // Verify namespace doesn't exist + assertThatThrownBy(() -> namespace.namespaceExists(existsRequest)) + .isInstanceOf(LanceNamespaceException.class); + } + + @Test + public void testTableOperations() { + String dbName = createTestDatabase(""); + String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8); + String tableLocation = tempDir.resolve(dbName).resolve(tableName + ".lance").toString(); + + // Create empty table + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); + createRequest.setId(Arrays.asList(dbName, tableName)); + createRequest.setLocation(tableLocation); + + CreateEmptyTableResponse createResponse = namespace.createEmptyTable(createRequest); + assertThat(createResponse.getLocation()).isNotNull(); + assertThat(createResponse.getLocation()).isEqualTo(tableLocation); + + // Describe table + DescribeTableRequest describeRequest = new DescribeTableRequest(); + describeRequest.setId(Arrays.asList(dbName, tableName)); + + DescribeTableResponse describeResponse = namespace.describeTable(describeRequest); + assertThat(describeResponse.getLocation()).isNotNull(); + assertThat(describeResponse.getLocation()).isEqualTo(tableLocation); + + // Check table exists + TableExistsRequest existsRequest = new TableExistsRequest(); + existsRequest.setId(Arrays.asList(dbName, tableName)); + namespace.tableExists(existsRequest); // Should not throw + + // List tables + ListTablesRequest listRequest = new ListTablesRequest(); + listRequest.setId(Collections.singletonList(dbName)); + + ListTablesResponse listResponse = namespace.listTables(listRequest); + assertThat(listResponse.getTables()).contains(tableName); + + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(dbName, tableName)); + namespace.deregisterTable(deregisterRequest); + + // Verify table doesn't exist + assertThatThrownBy(() -> namespace.tableExists(existsRequest)) + .isInstanceOf(LanceNamespaceException.class); + } + + @Test + public void testMultipleTablesInNamespace() { + String dbName = createTestDatabase(""); + List tableNames = new ArrayList<>(); + + // Create multiple tables + for (int i = 0; i < 3; i++) { + String tableName = "table_" + i + "_" + UUID.randomUUID().toString().substring(0, 6); + tableNames.add(tableName); + + String tableLocation = tempDir.resolve(dbName).resolve(tableName + ".lance").toString(); + CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); + createRequest.setId(Arrays.asList(dbName, tableName)); + createRequest.setLocation(tableLocation); + namespace.createEmptyTable(createRequest); + } + + // List tables and verify all are present + ListTablesRequest listRequest = new ListTablesRequest(); + listRequest.setId(Collections.singletonList(dbName)); + + ListTablesResponse listResponse = namespace.listTables(listRequest); + for (String tableName : tableNames) { + assertThat(listResponse.getTables()).contains(tableName); + } + + // Clean up tables + for (String tableName : tableNames) { + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(dbName, tableName)); + namespace.deregisterTable(deregisterRequest); + } + } +} diff --git a/python/Makefile b/python/Makefile index e649163..3408479 100644 --- a/python/Makefile +++ b/python/Makefile @@ -16,8 +16,8 @@ .PHONY: lint-glue lint-glue: - uv run ruff check src/lance_namespace_impls/glue.py tests/test_glue.py - uv run ruff format --check src/lance_namespace_impls/glue.py tests/test_glue.py + uv run ruff check src/lance_namespace_impls/glue.py tests/test_glue.py tests/test_glue_integration.py + uv run ruff format --check src/lance_namespace_impls/glue.py tests/test_glue.py tests/test_glue_integration.py .PHONY: install-glue install-glue: @@ -160,3 +160,7 @@ integ-test-unity: .PHONY: integ-test-iceberg integ-test-iceberg: uv run pytest tests/test_iceberg_integration.py -v + +.PHONY: integ-test-glue +integ-test-glue: + uv run pytest tests/test_glue_integration.py -v diff --git a/python/tests/test_glue_integration.py b/python/tests/test_glue_integration.py new file mode 100644 index 0000000..defbd1e --- /dev/null +++ b/python/tests/test_glue_integration.py @@ -0,0 +1,287 @@ +""" +Integration tests for AWS Glue namespace implementation. + +To run these tests locally: + 1. Configure AWS credentials (via environment variables, ~/.aws/credentials, or IAM role) + 2. Run: make integ-test-glue + +Tests are automatically skipped if AWS credentials are not available. +""" + +import os +import tempfile +import uuid +import unittest + +import pytest + +AWS_REGION = os.environ.get("AWS_REGION", "us-east-1") + + +def check_aws_credentials_available(): + """Check if AWS credentials are available.""" + if os.environ.get("AWS_ACCESS_KEY_ID") and os.environ.get("AWS_SECRET_ACCESS_KEY"): + return True + + try: + import boto3 + + sts = boto3.client("sts", region_name=AWS_REGION) + sts.get_caller_identity() + return True + except Exception: + return False + + +aws_credentials_available = check_aws_credentials_available() + + +@pytest.mark.integration +@unittest.skipUnless(aws_credentials_available, "AWS credentials are not available") +class TestGlueNamespaceIntegration(unittest.TestCase): + """Integration tests for GlueNamespace against a real AWS Glue catalog.""" + + @classmethod + def setUpClass(cls): + """Set up class-level resources.""" + from lance_namespace_impls.glue import GlueNamespace + + cls.temp_dir = tempfile.mkdtemp(prefix="lance_glue_test_") + cls.unique_id = uuid.uuid4().hex[:8] + cls.test_database = f"lance_test_db_{cls.unique_id}" + + properties = { + "region": AWS_REGION, + "root": cls.temp_dir, + } + + cls.namespace = GlueNamespace(**properties) + + @classmethod + def tearDownClass(cls): + """Clean up class-level resources.""" + if hasattr(cls, "namespace") and cls.namespace: + try: + cls._cleanup_database(cls.test_database) + except Exception: + pass + + import shutil + + if hasattr(cls, "temp_dir") and os.path.exists(cls.temp_dir): + shutil.rmtree(cls.temp_dir, ignore_errors=True) + + @classmethod + def _cleanup_database(cls, database_name): + """Helper to clean up a database and all its tables.""" + from lance_namespace_urllib3_client.models import ( + DropNamespaceRequest, + ListTablesRequest, + DeregisterTableRequest, + ) + + try: + list_request = ListTablesRequest() + list_request.id = [database_name] + response = cls.namespace.list_tables(list_request) + + for table_name in response.tables: + try: + dereg_request = DeregisterTableRequest() + dereg_request.id = [database_name, table_name] + cls.namespace.deregister_table(dereg_request) + except Exception: + pass + + drop_request = DropNamespaceRequest() + drop_request.id = [database_name] + cls.namespace.drop_namespace(drop_request) + except Exception: + pass + + def setUp(self): + """Set up test fixtures.""" + self.created_databases = [] + + def tearDown(self): + """Clean up test resources.""" + for db_name in self.created_databases: + try: + self._cleanup_database(db_name) + except Exception: + pass + + def _create_test_database(self, suffix=""): + """Helper to create a test database with tracking for cleanup.""" + from lance_namespace_urllib3_client.models import CreateNamespaceRequest + + db_name = f"lance_test_{uuid.uuid4().hex[:8]}{suffix}" + self.created_databases.append(db_name) + + create_request = CreateNamespaceRequest() + create_request.id = [db_name] + create_request.properties = {"description": "Lance integration test database"} + self.namespace.create_namespace(create_request) + return db_name + + def test_namespace_operations(self): + """Test namespace (database) CRUD operations.""" + from lance_namespace_urllib3_client.models import ( + CreateNamespaceRequest, + DescribeNamespaceRequest, + DropNamespaceRequest, + ListNamespacesRequest, + NamespaceExistsRequest, + ) + + db_name = f"lance_test_{uuid.uuid4().hex[:8]}" + self.created_databases.append(db_name) + + create_request = CreateNamespaceRequest() + create_request.id = [db_name] + create_request.properties = {"description": "Test database for Lance"} + + create_response = self.namespace.create_namespace(create_request) + self.assertIsNotNone(create_response) + + describe_request = DescribeNamespaceRequest() + describe_request.id = [db_name] + + describe_response = self.namespace.describe_namespace(describe_request) + self.assertIsNotNone(describe_response) + self.assertEqual( + describe_response.properties.get("description"), "Test database for Lance" + ) + + exists_request = NamespaceExistsRequest() + exists_request.id = [db_name] + self.namespace.namespace_exists(exists_request) + + list_request = ListNamespacesRequest() + list_request.id = [] + list_response = self.namespace.list_namespaces(list_request) + self.assertIn(db_name, list_response.namespaces) + + drop_request = DropNamespaceRequest() + drop_request.id = [db_name] + self.namespace.drop_namespace(drop_request) + self.created_databases.remove(db_name) + + with self.assertRaises(RuntimeError): + self.namespace.namespace_exists(exists_request) + + def test_table_operations(self): + """Test table CRUD operations.""" + from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + DescribeTableRequest, + DeregisterTableRequest, + ListTablesRequest, + TableExistsRequest, + ) + + db_name = self._create_test_database() + table_name = f"test_table_{uuid.uuid4().hex[:8]}" + table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + + create_request = CreateEmptyTableRequest() + create_request.id = [db_name, table_name] + create_request.location = table_location + + create_response = self.namespace.create_empty_table(create_request) + self.assertIsNotNone(create_response.location) + self.assertEqual(create_response.location, table_location) + + describe_request = DescribeTableRequest() + describe_request.id = [db_name, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertIsNotNone(describe_response.location) + self.assertEqual(describe_response.location, table_location) + + exists_request = TableExistsRequest() + exists_request.id = [db_name, table_name] + self.namespace.table_exists(exists_request) + + list_request = ListTablesRequest() + list_request.id = [db_name] + + list_response = self.namespace.list_tables(list_request) + self.assertIn(table_name, list_response.tables) + + deregister_request = DeregisterTableRequest() + deregister_request.id = [db_name, table_name] + self.namespace.deregister_table(deregister_request) + + with self.assertRaises(RuntimeError): + self.namespace.table_exists(exists_request) + + def test_register_existing_table(self): + """Test registering an existing Lance table.""" + import lance + import pyarrow as pa + from lance_namespace_urllib3_client.models import ( + DescribeTableRequest, + DeregisterTableRequest, + RegisterTableRequest, + ) + + db_name = self._create_test_database() + table_name = f"existing_table_{uuid.uuid4().hex[:8]}" + table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + + os.makedirs(os.path.dirname(table_location), exist_ok=True) + table = pa.table({"id": [1, 2, 3], "name": ["a", "b", "c"]}) + lance.write_dataset(table, table_location) + + register_request = RegisterTableRequest() + register_request.id = [db_name, table_name] + register_request.location = table_location + + register_response = self.namespace.register_table(register_request) + self.assertIsNotNone(register_response.location) + self.assertEqual(register_response.location, table_location) + + describe_request = DescribeTableRequest() + describe_request.id = [db_name, table_name] + + describe_response = self.namespace.describe_table(describe_request) + self.assertEqual(describe_response.location, table_location) + + deregister_request = DeregisterTableRequest() + deregister_request.id = [db_name, table_name] + self.namespace.deregister_table(deregister_request) + + def test_multiple_tables_in_namespace(self): + """Test creating and listing multiple tables in a namespace.""" + from lance_namespace_urllib3_client.models import ( + CreateEmptyTableRequest, + DeregisterTableRequest, + ListTablesRequest, + ) + + db_name = self._create_test_database() + table_names = [f"table_{i}_{uuid.uuid4().hex[:6]}" for i in range(3)] + + for table_name in table_names: + table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + create_request = CreateEmptyTableRequest() + create_request.id = [db_name, table_name] + create_request.location = table_location + self.namespace.create_empty_table(create_request) + + list_request = ListTablesRequest() + list_request.id = [db_name] + list_response = self.namespace.list_tables(list_request) + + for table_name in table_names: + self.assertIn(table_name, list_response.tables) + + for table_name in table_names: + deregister_request = DeregisterTableRequest() + deregister_request.id = [db_name, table_name] + self.namespace.deregister_table(deregister_request) + + +if __name__ == "__main__": + unittest.main() From 96c266ff1f48967fb578c303c01bb3107ff40f2b Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:01:09 -0800 Subject: [PATCH 10/20] python: remove non-basic operations from all implementations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove namespace_exists, table_exists, create_table, drop_table, and register_table from Python implementations as per basic operations spec. Only required operations are kept: create_namespace, list_namespaces, describe_namespace, drop_namespace, create_empty_table (declare_table), list_tables, describe_table, and deregister_table. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- python/src/lance_namespace_impls/glue.py | 185 +------------- python/src/lance_namespace_impls/hive2.py | 259 +------------------- python/src/lance_namespace_impls/hive3.py | 237 +----------------- python/src/lance_namespace_impls/iceberg.py | 82 ++++--- python/src/lance_namespace_impls/polaris.py | 24 +- python/src/lance_namespace_impls/unity.py | 52 +--- 6 files changed, 105 insertions(+), 734 deletions(-) diff --git a/python/src/lance_namespace_impls/glue.py b/python/src/lance_namespace_impls/glue.py index a2bd3c3..5ec803e 100644 --- a/python/src/lance_namespace_impls/glue.py +++ b/python/src/lance_namespace_impls/glue.py @@ -14,9 +14,6 @@ Config = None HAS_BOTO3 = False -import lance -import pyarrow as pa - from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, @@ -27,24 +24,17 @@ CreateNamespaceResponse, DropNamespaceRequest, DropNamespaceResponse, - NamespaceExistsRequest, ListTablesRequest, ListTablesResponse, - CreateTableRequest, - CreateTableResponse, CreateEmptyTableRequest, CreateEmptyTableResponse, - DropTableRequest, - DropTableResponse, DescribeTableRequest, DescribeTableResponse, - RegisterTableRequest, - RegisterTableResponse, DeregisterTableRequest, DeregisterTableResponse, - TableExistsRequest, ) +from lance_namespace_impls.rest_client import InvalidInputException LANCE_TABLE_TYPE = "LANCE" TABLE_TYPE = "table_type" @@ -282,6 +272,11 @@ def create_namespace( def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace (database) in Glue.""" + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + # Handle root namespace if not request.id or len(request.id) == 0: raise RuntimeError("Cannot drop root namespace") @@ -307,25 +302,6 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse raise raise RuntimeError(f"Failed to drop namespace: {e}") - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a namespace exists.""" - # Handle root namespace - it always exists - if not request.id or len(request.id) == 0: - return # Root namespace always exists - - if len(request.id) != 1: - raise ValueError("Glue namespace requires exactly one level identifier") - - database_name = request.id[0] - - try: - self.glue.get_database(Name=database_name) - except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" - if error_name == "EntityNotFoundException": - raise RuntimeError(f"Namespace does not exist: {database_name}") - raise RuntimeError(f"Failed to check namespace existence: {e}") - def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a namespace.""" # Handle root namespace - no tables at root level @@ -367,6 +343,11 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table.""" + if request.load_detailed_metadata: + raise RuntimeError( + "load_detailed_metadata=true is not supported for this implementation" + ) + database_name, table_name = self._parse_table_identifier(request.id) try: @@ -397,19 +378,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse raise raise RuntimeError(f"Failed to describe table: {e}") - def create_table( - self, request: CreateTableRequest, request_data: bytes - ) -> CreateTableResponse: - """Create a table with data from Arrow IPC stream. - - This operation is not supported. Use create_empty_table to declare table metadata, - then use Lance SDK to create the actual table data. - """ - raise NotImplementedError( - "create_table is not supported. Use create_empty_table to declare table metadata, " - "then use Lance SDK to create the actual table data." - ) - def create_empty_table( self, request: CreateEmptyTableRequest ) -> CreateEmptyTableResponse: @@ -473,59 +441,6 @@ def create_empty_table( return CreateEmptyTableResponse(location=table_location) - def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table - deletes both the Lance dataset and Glue catalog entry. - - This operation is not supported. Use deregister_table to remove table metadata, - then use Lance SDK to delete the actual table data if needed. - """ - raise NotImplementedError( - "drop_table is not supported. Use deregister_table to remove table metadata, " - "then use Lance SDK to delete the actual table data if needed." - ) - - def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: - """Register an existing Lance table in Glue.""" - database_name, table_name = self._parse_table_identifier(request.id) - - if not request.location: - raise ValueError("Location is required to register a table") - - # Read Lance dataset to get schema - try: - dataset = lance.dataset( - request.location, storage_options=self.config.storage_options - ) - schema = dataset.schema - except Exception as e: - raise RuntimeError( - f"Failed to read Lance dataset at {request.location}: {e}" - ) - - # Create Glue table entry - table_input = { - "Name": table_name, - "TableType": EXTERNAL_TABLE, - "Parameters": { - TABLE_TYPE: LANCE_TABLE_TYPE, - }, - "StorageDescriptor": { - "Location": request.location, - "Columns": self._convert_pyarrow_schema_to_glue_columns(schema), - }, - } - - try: - self.glue.create_table(DatabaseName=database_name, TableInput=table_input) - return RegisterTableResponse(location=request.location) - except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" - if error_name == "AlreadyExistsException": - raise RuntimeError( - f"Table already exists: {database_name}.{table_name}" - ) - raise RuntimeError(f"Failed to register table: {e}") - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: @@ -544,26 +459,6 @@ def deregister_table( ) raise RuntimeError(f"Failed to deregister table: {e}") - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists.""" - database_name, table_name = self._parse_table_identifier(request.id) - - try: - response = self.glue.get_table(DatabaseName=database_name, Name=table_name) - if not self._is_lance_table(response["Table"]): - raise RuntimeError( - f"Table is not a Lance table: {database_name}.{table_name}" - ) - except Exception as e: - error_name = e.__class__.__name__ if hasattr(e, "__class__") else "" - if error_name == "EntityNotFoundException": - raise RuntimeError( - f"Table does not exist: {database_name}.{table_name}" - ) - if isinstance(e, RuntimeError): - raise - raise RuntimeError(f"Failed to check table existence: {e}") - def _parse_table_identifier(self, identifier: List[str]) -> tuple[str, str]: """Parse table identifier into database and table name.""" if not identifier or len(identifier) != 2: @@ -579,64 +474,6 @@ def _is_lance_table(self, glue_table: Dict[str, Any]) -> bool: == LANCE_TABLE_TYPE ) - def _convert_pyarrow_schema_to_glue_columns( - self, schema: pa.Schema - ) -> List[Dict[str, str]]: - """Convert PyArrow schema to Glue column definitions.""" - columns = [] - for field in schema: - column = { - "Name": field.name, - "Type": self._convert_pyarrow_type_to_glue_type(field.type), - } - columns.append(column) - return columns - - def _convert_pyarrow_type_to_glue_type(self, arrow_type: pa.DataType) -> str: - """Convert PyArrow type to Glue/Hive type string.""" - if pa.types.is_boolean(arrow_type): - return "boolean" - elif pa.types.is_int8(arrow_type) or pa.types.is_uint8(arrow_type): - return "tinyint" - elif pa.types.is_int16(arrow_type) or pa.types.is_uint16(arrow_type): - return "smallint" - elif pa.types.is_int32(arrow_type) or pa.types.is_uint32(arrow_type): - return "int" - elif pa.types.is_int64(arrow_type) or pa.types.is_uint64(arrow_type): - return "bigint" - elif pa.types.is_float32(arrow_type): - return "float" - elif pa.types.is_float64(arrow_type): - return "double" - elif pa.types.is_string(arrow_type): - return "string" - elif pa.types.is_binary(arrow_type): - return "binary" - elif pa.types.is_date32(arrow_type) or pa.types.is_date64(arrow_type): - return "date" - elif pa.types.is_timestamp(arrow_type): - return "timestamp" - elif pa.types.is_decimal(arrow_type): - return f"decimal({arrow_type.precision},{arrow_type.scale})" - elif pa.types.is_list(arrow_type): - element_type = self._convert_pyarrow_type_to_glue_type( - arrow_type.value_type - ) - return f"array<{element_type}>" - elif pa.types.is_struct(arrow_type): - field_strs = [] - for field in arrow_type: - field_type = self._convert_pyarrow_type_to_glue_type(field.type) - field_strs.append(f"{field.name}:{field_type}") - return f"struct<{','.join(field_strs)}>" - elif pa.types.is_map(arrow_type): - key_type = self._convert_pyarrow_type_to_glue_type(arrow_type.key_type) - value_type = self._convert_pyarrow_type_to_glue_type(arrow_type.item_type) - return f"map<{key_type},{value_type}>" - else: - # Default to string for unknown types - return "string" - def __getstate__(self): """Prepare instance for pickling by excluding unpickleable objects.""" state = self.__dict__.copy() diff --git a/python/src/lance_namespace_impls/hive2.py b/python/src/lance_namespace_impls/hive2.py index d88fb58..68bd488 100644 --- a/python/src/lance_namespace_impls/hive2.py +++ b/python/src/lance_namespace_impls/hive2.py @@ -22,30 +22,6 @@ from lance_namespace import ListNamespacesRequest response = namespace.list_namespaces(ListNamespacesRequest()) - # Create a table - from lance_namespace import CreateTableRequest - import pyarrow as pa - import io - - data = pa.table({"col1": [1, 2, 3], "col2": ["a", "b", "c"]}) - buf = io.BytesIO() - with pa.ipc.new_stream(buf, data.schema) as writer: - writer.write_table(data) - - request = CreateTableRequest( - id=["my_database", "my_table"], - mode="create" - ) - response = namespace.create_table(request, buf.getvalue()) - - # Register existing Lance table - from lance_namespace import RegisterTableRequest - request = RegisterTableRequest( - id=["my_database", "existing_table"], - location="/path/to/lance/table" - ) - response = namespace.register_table(request) - Configuration Properties: uri (str): Hive Metastore Thrift URI (e.g., "thrift://localhost:9083") root (str): Storage root location of the lakehouse on Hive catalog (default: current working directory) @@ -87,9 +63,6 @@ InvalidOperationException = None MetaException = None -import lance -import pyarrow as pa - from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, @@ -100,24 +73,18 @@ CreateNamespaceResponse, DropNamespaceRequest, DropNamespaceResponse, - NamespaceExistsRequest, ListTablesRequest, ListTablesResponse, - CreateTableRequest, - CreateTableResponse, CreateEmptyTableRequest, CreateEmptyTableResponse, - DropTableRequest, - DropTableResponse, DescribeTableRequest, DescribeTableResponse, - RegisterTableRequest, - RegisterTableResponse, DeregisterTableRequest, DeregisterTableResponse, - TableExistsRequest, ) +from lance_namespace_impls.rest_client import InvalidInputException + logger = logging.getLogger(__name__) # Table properties used by Lance (per hive.md specification) @@ -331,6 +298,11 @@ def create_namespace( def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a database from the Hive Metastore. Only RESTRICT mode is supported.""" + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + try: # Cannot drop root namespace if self._is_root_namespace(request.id): @@ -357,26 +329,6 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse logger.error(f"Failed to drop namespace {request.id}: {e}") raise - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a database exists in the Hive Metastore.""" - try: - # Root namespace always exists - if self._is_root_namespace(request.id): - return - - if len(request.id) != 1: - raise ValueError(f"Invalid namespace identifier: {request.id}") - - database_name = request.id[0] - - with self.client as client: - client.get_database(database_name) - except Exception as e: - if NoSuchObjectException and isinstance(e, NoSuchObjectException): - raise ValueError(f"Namespace {request.id} does not exist") - logger.error(f"Failed to check namespace existence {request.id}: {e}") - raise - def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a database.""" try: @@ -421,6 +373,11 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse Only load_detailed_metadata=false is supported. Returns location and storage_options only. """ + if request.load_detailed_metadata: + raise ValueError( + "load_detailed_metadata=true is not supported for this implementation" + ) + try: database, table_name = self._normalize_identifier(request.id) @@ -448,137 +405,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse logger.error(f"Failed to describe table {request.id}: {e}") raise - def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: - """Register an existing Lance table in the Hive Metastore. - - Note: This will open the Lance dataset to get schema and version information. - If you want to avoid opening the dataset, you can provide 'version' in properties. - """ - try: - database, table_name = self._normalize_identifier(request.id) - - # Determine managed_by value - managed_by = ( - request.properties.get(MANAGED_BY_KEY, "storage") - if request.properties - else "storage" - ) - - # We always need to open the dataset to get schema for Hive columns - dataset = lance.dataset(request.location) - schema = dataset.schema - - # Only track version if managed_by is "impl" - version = None - if managed_by == "impl": - # Get version from properties or dataset - version = ( - request.properties.get(VERSION_KEY) if request.properties else None - ) - if version is None: - version = str(dataset.version) - - # Create Hive table object - if not HiveTable: - raise ImportError("Hive dependencies not available") - hive_table = HiveTable() - hive_table.dbName = database - hive_table.tableName = table_name - hive_table.owner = ( - request.properties.get("owner", os.getenv("USER", "")) - if request.properties - else os.getenv("USER", "") - ) - # Use current time if file doesn't exist yet - import time - - current_time = int(time.time()) - try: - hive_table.createTime = int(os.path.getctime(request.location)) - hive_table.lastAccessTime = int(os.path.getatime(request.location)) - except (OSError, FileNotFoundError): - hive_table.createTime = current_time - hive_table.lastAccessTime = current_time - hive_table.tableType = EXTERNAL_TABLE - - # Set storage descriptor - if not StorageDescriptor: - raise ImportError("Hive dependencies not available") - sd = StorageDescriptor() - sd.location = request.location - sd.inputFormat = "com.lancedb.lance.mapred.LanceInputFormat" - sd.outputFormat = "com.lancedb.lance.mapred.LanceOutputFormat" - sd.compressed = False - sd.cols = self._pyarrow_schema_to_hive_fields(schema) - - # Set SerDe info - if not SerDeInfo: - raise ImportError("Hive dependencies not available") - serde = SerDeInfo() - serde.serializationLib = "com.lancedb.lance.mapred.LanceSerDe" - sd.serdeInfo = serde - - hive_table.sd = sd - - # Set table parameters per hive.md specification - hive_table.parameters = { - TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, - MANAGED_BY_KEY: managed_by, - } - - # Only set version if managed_by is "impl" - if managed_by == "impl" and version is not None: - hive_table.parameters[VERSION_KEY] = version - - if request.properties: - # Add other properties but don't override the required ones - for k, v in request.properties.items(): - if k not in [TABLE_TYPE_KEY, MANAGED_BY_KEY, VERSION_KEY]: - hive_table.parameters[k] = v - - with self.client as client: - client.create_table(hive_table) - - return RegisterTableResponse( - location=request.location, properties=request.properties - ) - except Exception as e: - if AlreadyExistsException and isinstance(e, AlreadyExistsException): - raise ValueError(f"Table {request.id} already exists") - logger.error(f"Failed to register table {request.id}: {e}") - raise - - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists in the Hive Metastore.""" - try: - database, table_name = self._normalize_identifier(request.id) - - with self.client as client: - table = client.get_table(database, table_name) - - # Check if it's a Lance table (case insensitive) - if not table.parameters: - raise ValueError(f"Table {request.id} is not a Lance table") - table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() - if table_type != LANCE_TABLE_FORMAT: - raise ValueError(f"Table {request.id} is not a Lance table") - except Exception as e: - if NoSuchObjectException and isinstance(e, NoSuchObjectException): - raise ValueError(f"Table {request.id} does not exist") - logger.error(f"Failed to check table existence {request.id}: {e}") - raise - - def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table from the Hive Metastore. - - This operation is not supported. Use deregister_table to remove table metadata, - then use Lance SDK to delete the actual table data if needed. - """ - raise NotImplementedError( - "drop_table is not supported. Use deregister_table to remove table metadata, " - "then use Lance SDK to delete the actual table data if needed." - ) - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: @@ -609,19 +435,6 @@ def deregister_table( logger.error(f"Failed to deregister table {request.id}: {e}") raise - def create_table( - self, request: CreateTableRequest, request_data: bytes - ) -> CreateTableResponse: - """Create a new Lance table and register it in the Hive Metastore. - - This operation is not supported. Use create_empty_table to declare table metadata, - then use Lance SDK to create the actual table data. - """ - raise NotImplementedError( - "create_table is not supported. Use create_empty_table to declare table metadata, " - "then use Lance SDK to create the actual table data." - ) - def create_empty_table( self, request: CreateEmptyTableRequest ) -> CreateEmptyTableResponse: @@ -687,54 +500,6 @@ def create_empty_table( logger.error(f"Failed to create empty table {request.id}: {e}") raise - def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema]: - """Convert PyArrow schema to Hive field schemas.""" - fields = [] - for field in schema: - hive_type = self._pyarrow_type_to_hive_type(field.type) - if not FieldSchema: - raise ImportError("Hive dependencies not available") - hive_field = FieldSchema(name=field.name, type=hive_type, comment="") - fields.append(hive_field) - return fields - - def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: - """Convert PyArrow data type to Hive type string.""" - if pa.types.is_boolean(dtype): - return "boolean" - elif pa.types.is_int8(dtype): - return "tinyint" - elif pa.types.is_int16(dtype): - return "smallint" - elif pa.types.is_int32(dtype): - return "int" - elif pa.types.is_int64(dtype): - return "bigint" - elif pa.types.is_float32(dtype): - return "float" - elif pa.types.is_float64(dtype): - return "double" - elif pa.types.is_string(dtype): - return "string" - elif pa.types.is_binary(dtype): - return "binary" - elif pa.types.is_timestamp(dtype): - return "timestamp" - elif pa.types.is_date32(dtype) or pa.types.is_date64(dtype): - return "date" - elif pa.types.is_list(dtype): - inner_type = self._pyarrow_type_to_hive_type(dtype.value_type) - return f"array<{inner_type}>" - elif pa.types.is_struct(dtype): - field_strs = [] - for i in range(dtype.num_fields): - field = dtype.field(i) - field_type = self._pyarrow_type_to_hive_type(field.type) - field_strs.append(f"{field.name}:{field_type}") - return f"struct<{','.join(field_strs)}>" - else: - return "string" # Default to string for unknown types - def __getstate__(self): """Prepare instance for pickling by excluding unpickleable objects.""" state = self.__dict__.copy() diff --git a/python/src/lance_namespace_impls/hive3.py b/python/src/lance_namespace_impls/hive3.py index 0f259f1..1b44f7f 100644 --- a/python/src/lance_namespace_impls/hive3.py +++ b/python/src/lance_namespace_impls/hive3.py @@ -24,14 +24,6 @@ # List databases in a catalog response = namespace.list_namespaces(ListNamespacesRequest(id=["my_catalog"])) - # Register existing Lance table (3-level: catalog.database.table) - from lance_namespace import RegisterTableRequest - request = RegisterTableRequest( - id=["my_catalog", "my_database", "my_table"], - location="/path/to/lance/table" - ) - response = namespace.register_table(request) - Configuration Properties: uri (str): Hive Metastore Thrift URI (e.g., "thrift://localhost:9083") root (str): Storage root location of the lakehouse (default: current working directory) @@ -73,9 +65,6 @@ InvalidOperationException = None MetaException = None -import lance -import pyarrow as pa - from lance.namespace import LanceNamespace from lance_namespace_urllib3_client.models import ( ListNamespacesRequest, @@ -86,24 +75,18 @@ CreateNamespaceResponse, DropNamespaceRequest, DropNamespaceResponse, - NamespaceExistsRequest, ListTablesRequest, ListTablesResponse, - CreateTableRequest, - CreateTableResponse, CreateEmptyTableRequest, CreateEmptyTableResponse, - DropTableRequest, - DropTableResponse, DescribeTableRequest, DescribeTableResponse, - RegisterTableRequest, - RegisterTableResponse, DeregisterTableRequest, DeregisterTableResponse, - TableExistsRequest, ) +from lance_namespace_impls.rest_client import InvalidInputException + logger = logging.getLogger(__name__) TABLE_TYPE_KEY = "table_type" @@ -389,6 +372,11 @@ def create_namespace( def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace (catalog or database). Only RESTRICT mode is supported.""" + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + try: if self._is_root_namespace(request.id): raise ValueError("Cannot drop root namespace") @@ -421,32 +409,6 @@ def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse logger.error(f"Failed to drop namespace {request.id}: {e}") raise - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a namespace exists.""" - try: - if self._is_root_namespace(request.id): - return - - if len(request.id) == 1: - # Check catalog exists - # For simplicity, assume standard catalogs exist - return - - elif len(request.id) == 2: - # Check database exists - database_name = request.id[1].lower() - - with self.client as client: - client.get_database(database_name) - else: - raise ValueError(f"Invalid namespace identifier: {request.id}") - - except Exception as e: - if NoSuchObjectException and isinstance(e, NoSuchObjectException): - raise ValueError(f"Namespace {request.id} does not exist") - logger.error(f"Failed to check namespace existence {request.id}: {e}") - raise - def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: """List tables in a database.""" try: @@ -488,6 +450,11 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse Only load_detailed_metadata=false is supported. Returns location and storage_options only. """ + if request.load_detailed_metadata: + raise ValueError( + "load_detailed_metadata=true is not supported for this implementation" + ) + try: catalog, database, table_name = self._normalize_identifier(request.id) @@ -514,125 +481,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse logger.error(f"Failed to describe table {request.id}: {e}") raise - def register_table(self, request: RegisterTableRequest) -> RegisterTableResponse: - """Register an existing Lance table in the Hive Metastore.""" - try: - catalog, database, table_name = self._normalize_identifier(request.id) - - managed_by = ( - request.properties.get(MANAGED_BY_KEY, "storage") - if request.properties - else "storage" - ) - - dataset = lance.dataset(request.location) - schema = dataset.schema - - version = None - if managed_by == "impl": - version = ( - request.properties.get(VERSION_KEY) if request.properties else None - ) - if version is None: - version = str(dataset.version) - - if not HiveTable: - raise ImportError("Hive dependencies not available") - - hive_table = HiveTable() - hive_table.dbName = database - hive_table.tableName = table_name - hive_table.owner = ( - request.properties.get("owner", os.getenv("USER", "")) - if request.properties - else os.getenv("USER", "") - ) - - import time - - current_time = int(time.time()) - try: - hive_table.createTime = int(os.path.getctime(request.location)) - hive_table.lastAccessTime = int(os.path.getatime(request.location)) - except (OSError, FileNotFoundError): - hive_table.createTime = current_time - hive_table.lastAccessTime = current_time - hive_table.tableType = EXTERNAL_TABLE - - if not StorageDescriptor: - raise ImportError("Hive dependencies not available") - sd = StorageDescriptor() - sd.location = request.location - sd.inputFormat = "com.lancedb.lance.mapred.LanceInputFormat" - sd.outputFormat = "com.lancedb.lance.mapred.LanceOutputFormat" - sd.compressed = False - sd.cols = self._pyarrow_schema_to_hive_fields(schema) - - if not SerDeInfo: - raise ImportError("Hive dependencies not available") - serde = SerDeInfo() - serde.serializationLib = "com.lancedb.lance.mapred.LanceSerDe" - sd.serdeInfo = serde - - hive_table.sd = sd - - hive_table.parameters = { - TABLE_TYPE_KEY: LANCE_TABLE_FORMAT, - MANAGED_BY_KEY: managed_by, - } - - if managed_by == "impl" and version is not None: - hive_table.parameters[VERSION_KEY] = version - - if request.properties: - for k, v in request.properties.items(): - if k not in [TABLE_TYPE_KEY, MANAGED_BY_KEY, VERSION_KEY]: - hive_table.parameters[k] = v - - with self.client as client: - client.create_table(hive_table) - - return RegisterTableResponse( - location=request.location, properties=request.properties - ) - - except Exception as e: - if AlreadyExistsException and isinstance(e, AlreadyExistsException): - raise ValueError(f"Table {request.id} already exists") - logger.error(f"Failed to register table {request.id}: {e}") - raise - - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists.""" - try: - catalog, database, table_name = self._normalize_identifier(request.id) - - with self.client as client: - table = client.get_table(database, table_name) - - if not table.parameters: - raise ValueError(f"Table {request.id} is not a Lance table") - table_type = table.parameters.get(TABLE_TYPE_KEY, "").lower() - if table_type != LANCE_TABLE_FORMAT: - raise ValueError(f"Table {request.id} is not a Lance table") - - except Exception as e: - if NoSuchObjectException and isinstance(e, NoSuchObjectException): - raise ValueError(f"Table {request.id} does not exist") - logger.error(f"Failed to check table existence {request.id}: {e}") - raise - - def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table from the Hive Metastore. - - This operation is not supported. Use deregister_table to remove table metadata, - then use Lance SDK to delete the actual table data if needed. - """ - raise NotImplementedError( - "drop_table is not supported. Use deregister_table to remove table metadata, " - "then use Lance SDK to delete the actual table data if needed." - ) - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: @@ -661,19 +509,6 @@ def deregister_table( logger.error(f"Failed to deregister table {request.id}: {e}") raise - def create_table( - self, request: CreateTableRequest, request_data: bytes - ) -> CreateTableResponse: - """Create a new Lance table and register it. - - This operation is not supported. Use create_empty_table to declare table metadata, - then use Lance SDK to create the actual table data. - """ - raise NotImplementedError( - "create_table is not supported. Use create_empty_table to declare table metadata, " - "then use Lance SDK to create the actual table data." - ) - def create_empty_table( self, request: CreateEmptyTableRequest ) -> CreateEmptyTableResponse: @@ -732,54 +567,6 @@ def create_empty_table( logger.error(f"Failed to create empty table {request.id}: {e}") raise - def _pyarrow_schema_to_hive_fields(self, schema: pa.Schema) -> List[FieldSchema]: - """Convert PyArrow schema to Hive field schemas.""" - fields = [] - for field in schema: - hive_type = self._pyarrow_type_to_hive_type(field.type) - if not FieldSchema: - raise ImportError("Hive dependencies not available") - hive_field = FieldSchema(name=field.name, type=hive_type, comment="") - fields.append(hive_field) - return fields - - def _pyarrow_type_to_hive_type(self, dtype: pa.DataType) -> str: - """Convert PyArrow data type to Hive type string.""" - if pa.types.is_boolean(dtype): - return "boolean" - elif pa.types.is_int8(dtype): - return "tinyint" - elif pa.types.is_int16(dtype): - return "smallint" - elif pa.types.is_int32(dtype): - return "int" - elif pa.types.is_int64(dtype): - return "bigint" - elif pa.types.is_float32(dtype): - return "float" - elif pa.types.is_float64(dtype): - return "double" - elif pa.types.is_string(dtype): - return "string" - elif pa.types.is_binary(dtype): - return "binary" - elif pa.types.is_timestamp(dtype): - return "timestamp" - elif pa.types.is_date32(dtype) or pa.types.is_date64(dtype): - return "date" - elif pa.types.is_list(dtype): - inner_type = self._pyarrow_type_to_hive_type(dtype.value_type) - return f"array<{inner_type}>" - elif pa.types.is_struct(dtype): - field_strs = [] - for i in range(dtype.num_fields): - field = dtype.field(i) - field_type = self._pyarrow_type_to_hive_type(field.type) - field_strs.append(f"{field.name}:{field_type}") - return f"struct<{','.join(field_strs)}>" - else: - return "string" - def __getstate__(self): """Prepare instance for pickling.""" state = self.__dict__.copy() diff --git a/python/src/lance_namespace_impls/iceberg.py b/python/src/lance_namespace_impls/iceberg.py index fac64d0..c655eee 100644 --- a/python/src/lance_namespace_impls/iceberg.py +++ b/python/src/lance_namespace_impls/iceberg.py @@ -8,6 +8,7 @@ import logging import urllib.parse +import warnings from dataclasses import dataclass from typing import Any, Dict, List, Optional @@ -17,6 +18,8 @@ CreateEmptyTableResponse, CreateNamespaceRequest, CreateNamespaceResponse, + DeclareTableRequest, + DeclareTableResponse, DeregisterTableRequest, DeregisterTableResponse, DescribeNamespaceRequest, @@ -29,8 +32,6 @@ ListNamespacesResponse, ListTablesRequest, ListTablesResponse, - NamespaceExistsRequest, - TableExistsRequest, ) from lance_namespace_impls.rest_client import ( @@ -53,14 +54,14 @@ class IcebergNamespaceConfig: """Configuration for Iceberg REST Catalog namespace.""" - ENDPOINT = "iceberg.endpoint" - WAREHOUSE = "iceberg.warehouse" - AUTH_TOKEN = "iceberg.auth_token" - CREDENTIAL = "iceberg.credential" - CONNECT_TIMEOUT = "iceberg.connect_timeout_millis" - READ_TIMEOUT = "iceberg.read_timeout_millis" - MAX_RETRIES = "iceberg.max_retries" - ROOT = "iceberg.root" + ENDPOINT = "endpoint" + WAREHOUSE = "warehouse" + AUTH_TOKEN = "auth_token" + CREDENTIAL = "credential" + CONNECT_TIMEOUT = "connect_timeout" + READ_TIMEOUT = "read_timeout" + MAX_RETRIES = "max_retries" + ROOT = "root" endpoint: str warehouse: Optional[str] = None @@ -69,9 +70,11 @@ class IcebergNamespaceConfig: connect_timeout: int = 10000 read_timeout: int = 30000 max_retries: int = 3 - root: str = "/tmp/lance" + root: str = "" def __init__(self, properties: Dict[str, str]): + import os + self.endpoint = properties.get(self.ENDPOINT) if not self.endpoint: raise ValueError(f"Required property {self.ENDPOINT} is not set") @@ -82,7 +85,7 @@ def __init__(self, properties: Dict[str, str]): self.connect_timeout = int(properties.get(self.CONNECT_TIMEOUT, "10000")) self.read_timeout = int(properties.get(self.READ_TIMEOUT, "30000")) self.max_retries = int(properties.get(self.MAX_RETRIES, "3")) - self.root = properties.get(self.ROOT, "/tmp/lance") + self.root = properties.get(self.ROOT, os.getcwd()) def get_base_api_url(self) -> str: """Get the base API URL without prefix.""" @@ -307,18 +310,17 @@ def describe_namespace( except Exception as e: raise InternalException(f"Failed to describe namespace: {e}") - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a namespace exists.""" - describe_request = DescribeNamespaceRequest() - describe_request.id = request.id - self.describe_namespace(describe_request) - def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace. The first element of request.id is treated as the prefix (warehouse). Remaining elements are the namespace to drop. """ + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + ns_id = self._parse_identifier(request.id) if len(ns_id) < 2: @@ -399,10 +401,8 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: except Exception as e: raise InternalException(f"Failed to list tables: {e}") - def create_empty_table( - self, request: CreateEmptyTableRequest - ) -> CreateEmptyTableResponse: - """Create an empty table (metadata only operation). + def declare_table(self, request: DeclareTableRequest) -> DeclareTableResponse: + """Declare a table (metadata only operation). The first element of request.id is treated as the prefix (warehouse). Middle elements are the namespace, last element is the table name. @@ -441,9 +441,9 @@ def create_empty_table( f"{prefix_path}/namespaces/{namespace_path}/tables", create_request ) - logger.info(f"Created table: {'.'.join(table_id)}") + logger.info(f"Declared table: {'.'.join(table_id)}") - return CreateEmptyTableResponse(location=table_path) + return DeclareTableResponse(location=table_path) except RestClientException as e: if e.is_conflict(): @@ -454,7 +454,7 @@ def create_empty_table( raise NamespaceNotFoundException( f"Namespace not found: {prefix}.{'.'.join(namespace)}" ) - raise InternalException(f"Failed to create empty table: {e}") + raise InternalException(f"Failed to declare table: {e}") except ( TableAlreadyExistsException, NamespaceNotFoundException, @@ -462,7 +462,26 @@ def create_empty_table( ): raise except Exception as e: - raise InternalException(f"Failed to create empty table: {e}") + raise InternalException(f"Failed to declare table: {e}") + + def create_empty_table( + self, request: CreateEmptyTableRequest + ) -> CreateEmptyTableResponse: + """Create an empty table (metadata only operation). + + .. deprecated:: + Use :meth:`declare_table` instead. + """ + warnings.warn( + "create_empty_table is deprecated, use declare_table instead", + DeprecationWarning, + stacklevel=2, + ) + declare_request = DeclareTableRequest() + declare_request.id = request.id + declare_request.location = request.location + response = self.declare_table(declare_request) + return CreateEmptyTableResponse(location=response.location) def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table. @@ -470,6 +489,11 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse The first element of request.id is treated as the prefix (warehouse). Middle elements are the namespace, last element is the table name. """ + if request.load_detailed_metadata: + raise InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation" + ) + table_id = self._parse_identifier(request.id) if len(table_id) < 3: @@ -517,12 +541,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse except Exception as e: raise InternalException(f"Failed to describe table: {e}") - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists.""" - describe_request = DescribeTableRequest() - describe_request.id = request.id - self.describe_table(describe_request) - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: diff --git a/python/src/lance_namespace_impls/polaris.py b/python/src/lance_namespace_impls/polaris.py index 6315290..2dbcc21 100644 --- a/python/src/lance_namespace_impls/polaris.py +++ b/python/src/lance_namespace_impls/polaris.py @@ -24,8 +24,6 @@ ListNamespacesResponse, ListTablesRequest, ListTablesResponse, - NamespaceExistsRequest, - TableExistsRequest, ) from lance_namespace_impls.rest_client import ( @@ -216,14 +214,13 @@ def describe_namespace( except Exception as e: raise InternalException(f"Failed to describe namespace: {e}") - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a namespace exists.""" - describe_request = DescribeNamespaceRequest() - describe_request.id = request.id - self.describe_namespace(describe_request) - def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace. Only RESTRICT mode is supported.""" + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + ns_id = self._parse_identifier(request.id) if len(ns_id) < 2: @@ -350,6 +347,11 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse Only load_detailed_metadata=false is supported. Returns location and storage_options only. """ + if request.load_detailed_metadata: + raise InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation" + ) + table_id = self._parse_identifier(request.id) if len(table_id) < 3: @@ -393,12 +395,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse except Exception as e: raise InternalException(f"Failed to describe table: {e}") - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists.""" - describe_request = DescribeTableRequest() - describe_request.id = request.id - self.describe_table(describe_request) - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: diff --git a/python/src/lance_namespace_impls/unity.py b/python/src/lance_namespace_impls/unity.py index 8929a28..d70b4b2 100644 --- a/python/src/lance_namespace_impls/unity.py +++ b/python/src/lance_namespace_impls/unity.py @@ -16,8 +16,6 @@ CreateEmptyTableResponse, CreateNamespaceRequest, CreateNamespaceResponse, - CreateTableRequest, - CreateTableResponse, DeregisterTableRequest, DeregisterTableResponse, DescribeNamespaceRequest, @@ -26,14 +24,10 @@ DescribeTableResponse, DropNamespaceRequest, DropNamespaceResponse, - DropTableRequest, - DropTableResponse, ListNamespacesRequest, ListNamespacesResponse, ListTablesRequest, ListTablesResponse, - NamespaceExistsRequest, - TableExistsRequest, ) from lance_namespace_impls.rest_client import ( @@ -359,14 +353,13 @@ def describe_namespace( raise raise InternalException(f"Failed to describe namespace: {e}") - def namespace_exists(self, request: NamespaceExistsRequest) -> None: - """Check if a namespace exists.""" - describe_request = DescribeNamespaceRequest() - describe_request.id = request.id - self.describe_namespace(describe_request) - def drop_namespace(self, request: DropNamespaceRequest) -> DropNamespaceResponse: """Drop a namespace.""" + if request.behavior and request.behavior.lower() == "cascade": + raise InvalidInputException( + "Cascade behavior is not supported for this implementation" + ) + ns_id = self._parse_identifier(request.id) if len(ns_id) != 2: @@ -429,19 +422,6 @@ def list_tables(self, request: ListTablesRequest) -> ListTablesResponse: except Exception as e: raise InternalException(f"Failed to list tables: {e}") - def create_table( - self, request: CreateTableRequest, request_data: bytes - ) -> CreateTableResponse: - """Create a new table with data from Arrow IPC stream. - - This operation is not supported. Use create_empty_table to declare table metadata, - then use Lance SDK to create the actual table data. - """ - raise NotImplementedError( - "create_table is not supported. Use create_empty_table to declare table metadata, " - "then use Lance SDK to create the actual table data." - ) - def create_empty_table( self, request: CreateEmptyTableRequest ) -> CreateEmptyTableResponse: @@ -510,6 +490,11 @@ def create_empty_table( def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse: """Describe a table.""" + if request.load_detailed_metadata: + raise InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation" + ) + table_id = self._parse_identifier(request.id) if len(table_id) != 3: @@ -553,23 +538,6 @@ def describe_table(self, request: DescribeTableRequest) -> DescribeTableResponse raise raise InternalException(f"Failed to describe table: {e}") - def table_exists(self, request: TableExistsRequest) -> None: - """Check if a table exists.""" - describe_request = DescribeTableRequest() - describe_request.id = request.id - self.describe_table(describe_request) - - def drop_table(self, request: DropTableRequest) -> DropTableResponse: - """Drop a table. - - This operation is not supported. Use deregister_table to remove table metadata, - then use Lance SDK to delete the actual table data if needed. - """ - raise NotImplementedError( - "drop_table is not supported. Use deregister_table to remove table metadata, " - "then use Lance SDK to delete the actual table data if needed." - ) - def deregister_table( self, request: DeregisterTableRequest ) -> DeregisterTableResponse: From b01ddc4c1b991a2c7d7e6c6eabd405eb1ce32ced Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:03:54 -0800 Subject: [PATCH 11/20] java/glue: remove non-basic operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove registerTable, namespaceExists, and tableExists from GlueNamespace as per basic operations spec. Only required operations are kept. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../lance/namespace/glue/GlueNamespace.java | 91 ++----------------- 1 file changed, 9 insertions(+), 82 deletions(-) diff --git a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java index 0e13300..847c691 100644 --- a/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java +++ b/java/lance-namespace-glue/src/main/java/org/lance/namespace/glue/GlueNamespace.java @@ -36,10 +36,6 @@ import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; -import org.lance.namespace.model.NamespaceExistsRequest; -import org.lance.namespace.model.RegisterTableRequest; -import org.lance.namespace.model.RegisterTableResponse; -import org.lance.namespace.model.TableExistsRequest; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; @@ -185,6 +181,10 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + String namespaceName = namespaceFromId(request.getId()); String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; @@ -203,13 +203,6 @@ public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { return new DropNamespaceResponse(); } - @Override - public void namespaceExists(NamespaceExistsRequest request) { - String namespaceName = namespaceFromId(request.getId()); - // Throws if database doesn't exist - getDatabase(namespaceName); - } - @Override public ListTablesResponse listTables(ListTablesRequest request) { String namespaceName = namespaceFromId(request.getId()); @@ -243,6 +236,11 @@ public ListTablesResponse listTables(ListTablesRequest request) { @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + validateTableId(request.getId()); String namespaceName = request.getId().get(0); String tableName = request.getId().get(1); @@ -258,65 +256,6 @@ public DescribeTableResponse describeTable(DescribeTableRequest request) { return response; } - @Override - public RegisterTableResponse registerTable(RegisterTableRequest request) { - validateTableId(request.getId()); - String namespaceName = request.getId().get(0); - String tableName = request.getId().get(1); - - if (request.getLocation() == null || request.getLocation().isEmpty()) { - throw new InvalidInputException("Table location is required", "BAD_REQUEST", ""); - } - String location = request.getLocation(); - location = - location != null && location.endsWith("/") - ? location.substring(0, location.length() - 1) - : location; - String mode = request.getMode() != null ? request.getMode().toLowerCase() : "create"; - - if ("overwrite".equals(mode)) { - deleteGlueTable(namespaceName, tableName, false); - } - - try { - // TODO: register table mode - Map params = Maps.newHashMap(); - if (request.getProperties() != null) { - params.putAll(request.getProperties()); - } - params.put(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE); - params.put(MANAGED_BY_PROP, STORAGE_VALUE); // Always storage for existing tables - - TableInput tableInput = - TableInput.builder() - .name(tableName) - .storageDescriptor( - StorageDescriptor.builder().location(location).parameters(params).build()) - .build(); - - glueClient.createTable( - software.amazon.awssdk.services.glue.model.CreateTableRequest.builder() - .catalogId(config.catalogId()) - .databaseName(namespaceName) - .tableInput(tableInput) - .build()); - - RegisterTableResponse response = new RegisterTableResponse(); - response.setLocation(location); - response.setProperties(request.getProperties()); - return response; - } catch (AlreadyExistsException e) { - throw GlueToLanceErrorConverter.tableConflict( - e, "Table already exists: %s.%s", namespaceName, tableName); - } catch (EntityNotFoundException e) { - throw GlueToLanceErrorConverter.namespaceNotFound( - e, "Namespace not found: %s", namespaceName); - } catch (GlueException e) { - throw GlueToLanceErrorConverter.serverError( - e, "Failed to register table: %s.%s", namespaceName, tableName); - } - } - @Override public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { validateTableId(request.getId()); @@ -396,18 +335,6 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request } } - // Removed: dropTable(DropTableRequest) - using default implementation from interface - - @Override - public void tableExists(TableExistsRequest request) { - validateTableId(request.getId()); - String namespaceName = request.getId().get(0); - String tableName = request.getId().get(1); - - Table table = getGlueTableAtVersion(namespaceName, tableName, request.getVersion()); - ensureLanceTable(table); - } - private void validateParent(List id) { if (id != null && id.size() > 1) { String instance = String.join("/", id); From 13f04fd9a47e7bd846debfcf07d31a8faa8bfbf3 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:07:42 -0800 Subject: [PATCH 12/20] fix: remove non-basic operation tests from test_glue.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove tests for namespace_exists, table_exists, create_table, drop_table, register_table, and pyarrow conversion methods that were removed from the implementation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- python/pyproject.toml | 2 +- python/tests/test_glue.py | 208 +---------------------- python/tests/test_iceberg.py | 22 +-- python/tests/test_iceberg_integration.py | 4 +- python/uv.lock | 14 +- 5 files changed, 24 insertions(+), 226 deletions(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index 8ce7cb2..055d965 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -12,7 +12,7 @@ requires-python = ">=3.10" dependencies = [ "pylance>=0.26.0", - "lance-namespace-urllib3-client>=0.0.21", + "lance-namespace-urllib3-client>=0.4.2", "pyarrow>=15.0.0", "typing-extensions>=4.5.0", ] diff --git a/python/tests/test_glue.py b/python/tests/test_glue.py index b215458..0893bfb 100644 --- a/python/tests/test_glue.py +++ b/python/tests/test_glue.py @@ -4,7 +4,6 @@ import pytest from unittest.mock import MagicMock, patch -import pyarrow as pa from lance_namespace_impls.glue import GlueNamespace, GlueNamespaceConfig from lance_namespace_urllib3_client.models import ( @@ -12,14 +11,9 @@ CreateNamespaceRequest, DescribeNamespaceRequest, DropNamespaceRequest, - NamespaceExistsRequest, ListTablesRequest, - CreateTableRequest, - DropTableRequest, DescribeTableRequest, - RegisterTableRequest, DeregisterTableRequest, - TableExistsRequest, ) @@ -32,14 +26,7 @@ def mock_boto3(): @pytest.fixture -def mock_lance(): - """Mock lance module.""" - with patch("lance_namespace_impls.glue.lance") as mock: - yield mock - - -@pytest.fixture -def glue_namespace(mock_boto3, mock_lance): +def glue_namespace(mock_boto3): """Create a GlueNamespace instance with mocked dependencies.""" properties = {"region": "us-east-1", "catalog_id": "123456789012"} namespace = GlueNamespace(**properties) @@ -253,41 +240,6 @@ def test_drop_namespace_not_empty(self, glue_namespace): with pytest.raises(RuntimeError, match="Cannot drop non-empty namespace"): glue_namespace.drop_namespace(request) - def test_namespace_exists_root(self, glue_namespace): - """Test checking if root namespace exists.""" - request = NamespaceExistsRequest(id=[]) - glue_namespace.namespace_exists(request) # Should not raise - - glue_namespace.glue.get_database.assert_not_called() - - def test_namespace_exists(self, glue_namespace): - """Test checking if a namespace exists.""" - glue_namespace.glue.get_database.return_value = { - "Database": {"Name": "test_db"} - } - - request = NamespaceExistsRequest(id=["test_db"]) - glue_namespace.namespace_exists(request) # Should not raise - - glue_namespace.glue.get_database.assert_called_once_with(Name="test_db") - - def test_namespace_not_exists(self, glue_namespace): - """Test checking if a namespace doesn't exist.""" - - # Create a custom exception with the right name - class EntityNotFoundException(Exception): - pass - - glue_namespace.glue.exceptions.EntityNotFoundException = EntityNotFoundException - glue_namespace.glue.get_database.side_effect = EntityNotFoundException( - "Not found" - ) - - request = NamespaceExistsRequest(id=["test_db"]) - - with pytest.raises(RuntimeError, match="Namespace does not exist"): - glue_namespace.namespace_exists(request) - def test_list_tables_root(self, glue_namespace): """Test listing tables at root namespace returns empty.""" request = ListTablesRequest(id=[]) @@ -315,27 +267,11 @@ def test_list_tables(self, glue_namespace): assert response.tables == ["table1", "table2"] glue_namespace.glue.get_tables.assert_called_once_with(DatabaseName="test_db") - def test_create_table_not_supported(self, glue_namespace, mock_lance): - """Test that create_table raises NotImplementedError.""" - request = CreateTableRequest(id=["test_db", "test_table"]) - - with pytest.raises(NotImplementedError, match="create_table is not supported"): - glue_namespace.create_table(request, b"test_data") - - def test_drop_table_not_supported(self, glue_namespace, mock_lance): - """Test that drop_table raises NotImplementedError.""" - request = DropTableRequest(id=["test_db", "test_table"]) - - with pytest.raises(NotImplementedError, match="drop_table is not supported"): - glue_namespace.drop_table(request) - - def test_deregister_table(self, glue_namespace, mock_lance): + def test_deregister_table(self, glue_namespace): """Test deregistering a table (only removes from Glue, keeps Lance dataset).""" request = DeregisterTableRequest(id=["test_db", "test_table"]) glue_namespace.deregister_table(request) - # Verify only Glue table was deleted (no Lance operations) - mock_lance.dataset.assert_not_called() glue_namespace.glue.delete_table.assert_called_once_with( DatabaseName="test_db", Name="test_table" ) @@ -370,66 +306,6 @@ def test_describe_table_not_lance(self, glue_namespace): with pytest.raises(RuntimeError, match="Table is not a Lance table"): glue_namespace.describe_table(request) - def test_register_table(self, glue_namespace, mock_lance): - """Test registering an existing table.""" - # Mock Lance dataset - mock_dataset = MagicMock() - mock_dataset.schema = pa.schema( - [ - pa.field("id", pa.int64()), - pa.field("name", pa.string()), - ] - ) - mock_lance.dataset.return_value = mock_dataset - - request = RegisterTableRequest( - id=["test_db", "test_table"], location="s3://bucket/existing_table.lance" - ) - - response = glue_namespace.register_table(request) - - assert response.location == "s3://bucket/existing_table.lance" - - # Verify Lance dataset was read - mock_lance.dataset.assert_called_once_with( - "s3://bucket/existing_table.lance", storage_options={} - ) - - # Verify Glue table was created - glue_namespace.glue.create_table.assert_called_once() - call_args = glue_namespace.glue.create_table.call_args - assert call_args[1]["DatabaseName"] == "test_db" - assert call_args[1]["TableInput"]["Name"] == "test_table" - assert call_args[1]["TableInput"]["Parameters"]["table_type"] == "LANCE" - - def test_table_exists(self, glue_namespace): - """Test checking if a table exists.""" - glue_namespace.glue.get_table.return_value = { - "Table": {"Name": "test_table", "Parameters": {"table_type": "LANCE"}} - } - - request = TableExistsRequest(id=["test_db", "test_table"]) - glue_namespace.table_exists(request) # Should not raise - - glue_namespace.glue.get_table.assert_called_once_with( - DatabaseName="test_db", Name="test_table" - ) - - def test_table_not_exists(self, glue_namespace): - """Test checking if a table doesn't exist.""" - - # Create a custom exception with the right name - class EntityNotFoundException(Exception): - pass - - glue_namespace.glue.exceptions.EntityNotFoundException = EntityNotFoundException - glue_namespace.glue.get_table.side_effect = EntityNotFoundException("Not found") - - request = TableExistsRequest(id=["test_db", "test_table"]) - - with pytest.raises(RuntimeError, match="Table does not exist"): - glue_namespace.table_exists(request) - def test_parse_table_identifier(self, glue_namespace): """Test parsing table identifier.""" db, table = glue_namespace._parse_table_identifier(["db", "table"]) @@ -456,86 +332,6 @@ def test_is_lance_table(self, glue_namespace): no_params = {} assert glue_namespace._is_lance_table(no_params) is False - def test_pyarrow_type_conversions(self, glue_namespace): - """Test PyArrow to Glue type conversions.""" - # Test basic types - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.bool_()) == "boolean" - ) - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int32()) == "int" - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.int64()) == "bigint" - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.float32()) == "float" - ) - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.float64()) == "double" - ) - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.string()) == "string" - ) - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.binary()) == "binary" - ) - assert glue_namespace._convert_pyarrow_type_to_glue_type(pa.date32()) == "date" - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.timestamp("us")) - == "timestamp" - ) - - # Test complex types - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.list_(pa.int32())) - == "array" - ) - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type( - pa.struct([pa.field("a", pa.int32()), pa.field("b", pa.string())]) - ) - == "struct" - ) - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type( - pa.map_(pa.string(), pa.int32()) - ) - == "map" - ) - - # Test decimal - assert ( - glue_namespace._convert_pyarrow_type_to_glue_type(pa.decimal128(10, 2)) - == "decimal(10,2)" - ) - - def test_pyarrow_schema_to_glue_columns(self, glue_namespace): - """Test conversion of PyArrow schema to Glue column definitions.""" - schema = pa.schema( - [ - pa.field("id", pa.int64()), - pa.field("name", pa.string()), - pa.field("scores", pa.list_(pa.float32())), - pa.field( - "metadata", - pa.struct( - [ - pa.field("created", pa.timestamp("us")), - pa.field("version", pa.int32()), - ] - ), - ), - ] - ) - - columns = glue_namespace._convert_pyarrow_schema_to_glue_columns(schema) - - assert len(columns) == 4 - assert columns[0] == {"Name": "id", "Type": "bigint"} - assert columns[1] == {"Name": "name", "Type": "string"} - assert columns[2] == {"Name": "scores", "Type": "array"} - assert columns[3] == { - "Name": "metadata", - "Type": "struct", - } - def test_pickle_support(self, mock_boto3): """Test that GlueNamespace can be pickled and unpickled for Ray compatibility.""" import pickle diff --git a/python/tests/test_iceberg.py b/python/tests/test_iceberg.py index 27a28ac..f3a1061 100644 --- a/python/tests/test_iceberg.py +++ b/python/tests/test_iceberg.py @@ -36,10 +36,10 @@ class TestIcebergNamespaceConfig(unittest.TestCase): def test_config_initialization(self): """Test configuration initialization with required properties.""" properties = { - "iceberg.endpoint": "https://iceberg.example.com", - "iceberg.root": "/data/lance", - "iceberg.auth_token": "test_token", - "iceberg.warehouse": "test_warehouse", + "endpoint": "https://iceberg.example.com", + "root": "/data/lance", + "auth_token": "test_token", + "warehouse": "test_warehouse", } config = IcebergNamespaceConfig(properties) @@ -51,11 +51,13 @@ def test_config_initialization(self): def test_config_defaults(self): """Test configuration with default values.""" - properties = {"iceberg.endpoint": "https://iceberg.example.com"} + import os + + properties = {"endpoint": "https://iceberg.example.com"} config = IcebergNamespaceConfig(properties) - self.assertEqual(config.root, "/tmp/lance") + self.assertEqual(config.root, os.getcwd()) self.assertIsNone(config.auth_token) self.assertIsNone(config.warehouse) self.assertEqual(config.connect_timeout, 10000) @@ -69,11 +71,11 @@ def test_config_missing_endpoint(self): with self.assertRaises(ValueError) as context: IcebergNamespaceConfig(properties) - self.assertIn("iceberg.endpoint", str(context.exception)) + self.assertIn("endpoint", str(context.exception)) def test_get_base_api_url(self): """Test API URL generation.""" - properties = {"iceberg.endpoint": "https://iceberg.example.com/"} + properties = {"endpoint": "https://iceberg.example.com/"} config = IcebergNamespaceConfig(properties) self.assertEqual(config.get_base_api_url(), "https://iceberg.example.com") @@ -85,8 +87,8 @@ class TestIcebergNamespace(unittest.TestCase): def setUp(self): """Set up test fixtures.""" self.properties = { - "iceberg.endpoint": "https://iceberg.example.com", - "iceberg.root": "/data/lance", + "endpoint": "https://iceberg.example.com", + "root": "/data/lance", } @patch("lance_namespace_impls.iceberg.RestClient") diff --git a/python/tests/test_iceberg_integration.py b/python/tests/test_iceberg_integration.py index bda8eac..53d5ed5 100644 --- a/python/tests/test_iceberg_integration.py +++ b/python/tests/test_iceberg_integration.py @@ -70,8 +70,8 @@ def setUp(self): self.test_namespace = f"test_ns_{unique_id}" properties = { - "iceberg.endpoint": ICEBERG_ENDPOINT, - "iceberg.root": "s3://warehouse", + "endpoint": ICEBERG_ENDPOINT, + "root": "s3://warehouse", } self.namespace = IcebergNamespace(**properties) diff --git a/python/uv.lock b/python/uv.lock index cca2d01..fad9ad7 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -200,14 +200,14 @@ wheels = [ [[package]] name = "lance-namespace" -version = "0.4.0" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "lance-namespace-urllib3-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/8d/b117539252afc81b0fb94301e5543516af8594a70242ef247bc88c03cbdc/lance_namespace-0.4.0.tar.gz", hash = "sha256:aedfb5f4413ead9c5f0d2a351fe47b0b68a1dec0dd4331a88f54bce3491f630f", size = 9827, upload-time = "2025-12-21T16:07:51.349Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/af/a77e7c9bc16ccf8a793df06bb87a559198f5b5dfb7ca03f4f32e1fe9cc15/lance_namespace-0.4.2.tar.gz", hash = "sha256:6830d0fb0f3f6dc0388ace2aa1a29f1b8e22c62f22e592a8b578c5da92980e7b", size = 9828, upload-time = "2025-12-31T08:31:02.488Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/fe/edbeb9ae7408685e90b2f0609c2f84bc3ef2f65d82bb4dce394de6d9c317/lance_namespace-0.4.0-py3-none-any.whl", hash = "sha256:7d91ee199a9864535ea17bd41787726c06b7ec8efbf06f7275bc54ea9998264f", size = 11701, upload-time = "2025-12-21T16:07:50.368Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9a/13242c23f932d8a61288e7c3e5bf5929cd509947535175d0f1ff188c6562/lance_namespace-0.4.2-py3-none-any.whl", hash = "sha256:ad0705dc0fdf37494cccc7163272472b773ad08572b146173114167187e5825e", size = 11702, upload-time = "2025-12-31T08:31:05.309Z" }, ] [[package]] @@ -255,7 +255,7 @@ requires-dist = [ { name = "hive-metastore-client", marker = "extra == 'all'", specifier = ">=1.0.0" }, { name = "hive-metastore-client", marker = "extra == 'hive2'", specifier = ">=1.0.0" }, { name = "hive-metastore-client", marker = "extra == 'hive3'", specifier = ">=1.0.0" }, - { name = "lance-namespace-urllib3-client", specifier = ">=0.0.21" }, + { name = "lance-namespace-urllib3-client", specifier = ">=0.4.2" }, { name = "pyarrow", specifier = ">=15.0.0" }, { name = "pylance", specifier = ">=0.26.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.0.0" }, @@ -270,7 +270,7 @@ provides-extras = ["glue", "hive2", "hive3", "iceberg", "polaris", "unity", "all [[package]] name = "lance-namespace-urllib3-client" -version = "0.4.0" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, @@ -278,9 +278,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4c/a2/53643e7ea756cd8c4275219f555a554db340d1e4e7366df39a79d9bd092d/lance_namespace_urllib3_client-0.4.0.tar.gz", hash = "sha256:896bf9336f5b14f5acc0d45ca956e291e0fcc2a0e56c1efe52723c23ae3a3296", size = 154577, upload-time = "2025-12-21T16:07:53.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/33/3f533d87b8ad0867181a86cb17517cabed277d6816ca66a676dd98076064/lance_namespace_urllib3_client-0.4.2.tar.gz", hash = "sha256:294bfd2579f640053486008a77c2b7d43b8bf9614217941eda51b6f1c0f42f28", size = 155837, upload-time = "2025-12-31T08:31:04.605Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/1f/050c1ed613b0ec017fa3b85d35d52658ead1158d95a092c1b83578d39ab5/lance_namespace_urllib3_client-0.4.0-py3-none-any.whl", hash = "sha256:858b44b4b34b4ae8f4d905e10a89e4b14f08213dca9dd6751be09cfa03a7dbdc", size = 261516, upload-time = "2025-12-21T16:07:51.946Z" }, + { url = "https://files.pythonhosted.org/packages/c2/79/c67652374a99c14e751fc4c16592b3d20c2f855ffc52c77132b3b48e356c/lance_namespace_urllib3_client-0.4.2-py3-none-any.whl", hash = "sha256:da885fd62b37af8653dba7ed22322bfd0a92a60ce78214eebca76783041af668", size = 262107, upload-time = "2025-12-31T08:31:03.431Z" }, ] [[package]] From ad25eaccb7c4c8e47b393ba93f0aef773b5fff3e Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:12:55 -0800 Subject: [PATCH 13/20] fix: remove non-basic operation tests from hive2, hive3, unity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove tests for namespace_exists, table_exists, create_table, drop_table, and register_table from test files. These operations were removed from the implementations as per basic operations spec. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- python/tests/test_hive2.py | 188 ------------------------------------- python/tests/test_hive3.py | 94 ------------------- python/tests/test_unity.py | 34 ------- 3 files changed, 316 deletions(-) diff --git a/python/tests/test_hive2.py b/python/tests/test_hive2.py index 2252881..5811570 100644 --- a/python/tests/test_hive2.py +++ b/python/tests/test_hive2.py @@ -2,11 +2,8 @@ Tests for Lance Hive2 Namespace implementation. """ -import os import pytest -import tempfile from unittest.mock import MagicMock, patch -import pyarrow as pa from lance_namespace_impls.hive2 import Hive2Namespace from lance_namespace_urllib3_client.models import ( @@ -14,13 +11,9 @@ DescribeNamespaceRequest, CreateNamespaceRequest, DropNamespaceRequest, - NamespaceExistsRequest, ListTablesRequest, DescribeTableRequest, - RegisterTableRequest, DeregisterTableRequest, - TableExistsRequest, - DropTableRequest, ) @@ -170,16 +163,6 @@ def test_drop_namespace_not_empty_fails(self, hive_namespace, mock_hive_client): with pytest.raises(ValueError, match="is not empty"): hive_namespace.drop_namespace(request) - def test_namespace_exists(self, hive_namespace, mock_hive_client): - """Test checking if a namespace exists.""" - mock_client_instance = MagicMock() - mock_hive_client.__enter__.return_value = mock_client_instance - - request = NamespaceExistsRequest(id=["test_db"]) - hive_namespace.namespace_exists(request) - - mock_client_instance.get_database.assert_called_once_with("test_db") - def test_list_tables(self, hive_namespace, mock_hive_client): """Test listing tables in a namespace.""" mock_table1 = MagicMock() @@ -241,173 +224,6 @@ def test_describe_table(self, hive_namespace, mock_hive_client): mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - def test_register_table(self, hive_namespace, mock_hive_client): - """Test registering a Lance table.""" - with tempfile.TemporaryDirectory() as tmpdir: - # Create a mock Lance dataset - table_path = os.path.join(tmpdir, "test_table") - - # Create sample data - data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) - - with patch( - "lance_namespace_impls.hive2.lance.dataset" - ) as mock_dataset_func: - mock_dataset = MagicMock() - mock_dataset.schema = data.schema - mock_dataset.version = 1 - mock_dataset_func.return_value = mock_dataset - - mock_client_instance = MagicMock() - mock_hive_client.__enter__.return_value = mock_client_instance - - # Mock all Hive classes - with ( - patch( - "lance_namespace_impls.hive2.HiveTable" - ) as mock_hive_table_class, - patch( - "lance_namespace_impls.hive2.StorageDescriptor" - ) as mock_sd_class, - patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, - patch( - "lance_namespace_impls.hive2.FieldSchema" - ) as mock_field_class, - ): - mock_hive_table = MagicMock() - mock_hive_table_class.return_value = mock_hive_table - mock_sd = MagicMock() - mock_sd_class.return_value = mock_sd - mock_serde = MagicMock() - mock_serde_class.return_value = mock_serde - mock_field_class.return_value = MagicMock() - - request = RegisterTableRequest( - id=["test_db", "test_table"], - location=table_path, - properties={"owner": "test_user"}, - ) - response = hive_namespace.register_table(request) - - # Response only includes location - assert response.location == table_path - - mock_client_instance.create_table.assert_called_once_with( - mock_hive_table - ) - - # Verify the table object properties were set - assert mock_hive_table.dbName == "test_db" - assert mock_hive_table.tableName == "test_table" - assert mock_hive_table.tableType == "EXTERNAL_TABLE" - assert mock_sd.location == table_path - # Verify Lance-specific input/output formats - assert ( - mock_sd.inputFormat - == "com.lancedb.lance.mapred.LanceInputFormat" - ) - assert ( - mock_sd.outputFormat - == "com.lancedb.lance.mapred.LanceOutputFormat" - ) - # Verify SerDe configuration - assert mock_sd.serdeInfo == mock_serde - assert ( - mock_serde.serializationLib - == "com.lancedb.lance.mapred.LanceSerDe" - ) - assert mock_hive_table.parameters["table_type"] == "lance" - assert ( - mock_hive_table.parameters["managed_by"] == "storage" - ) # Default - assert ( - "version" not in mock_hive_table.parameters - ) # Not set for storage-managed - assert ( - "EXTERNAL" not in mock_hive_table.parameters - ) # Should not be present - assert mock_hive_table.parameters["owner"] == "test_user" - - def test_register_table_impl_managed(self, hive_namespace, mock_hive_client): - """Test registering a Lance table with managed_by=impl.""" - with tempfile.TemporaryDirectory() as tmpdir: - # Create a mock Lance dataset - table_path = os.path.join(tmpdir, "test_table") - - # Create sample data - data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) - - with patch( - "lance_namespace_impls.hive2.lance.dataset" - ) as mock_dataset_func: - mock_dataset = MagicMock() - mock_dataset.schema = data.schema - mock_dataset.version = 42 - mock_dataset_func.return_value = mock_dataset - - mock_client_instance = MagicMock() - mock_hive_client.__enter__.return_value = mock_client_instance - - # Mock all Hive classes - with ( - patch( - "lance_namespace_impls.hive2.HiveTable" - ) as mock_hive_table_class, - patch( - "lance_namespace_impls.hive2.StorageDescriptor" - ) as mock_sd_class, - patch("lance_namespace_impls.hive2.SerDeInfo") as mock_serde_class, - patch( - "lance_namespace_impls.hive2.FieldSchema" - ) as mock_field_class, - ): - mock_hive_table = MagicMock() - mock_hive_table_class.return_value = mock_hive_table - mock_sd = MagicMock() - mock_sd_class.return_value = mock_sd - mock_serde = MagicMock() - mock_serde_class.return_value = mock_serde - mock_field_class.return_value = MagicMock() - - request = RegisterTableRequest( - id=["test_db", "test_table"], - location=table_path, - properties={"owner": "test_user", "managed_by": "impl"}, - ) - hive_namespace.register_table(request) - - # Verify version is set when managed_by is "impl" - assert mock_hive_table.parameters["table_type"] == "lance" - assert mock_hive_table.parameters["managed_by"] == "impl" - assert ( - mock_hive_table.parameters["version"] == "42" - ) # Version should be set - assert ( - "EXTERNAL" not in mock_hive_table.parameters - ) # Should not be present - assert mock_hive_table.parameters["owner"] == "test_user" - - def test_table_exists(self, hive_namespace, mock_hive_client): - """Test checking if a table exists.""" - mock_table = MagicMock() - mock_table.parameters = {"table_type": "lance"} - - mock_client_instance = MagicMock() - mock_client_instance.get_table.return_value = mock_table - mock_hive_client.__enter__.return_value = mock_client_instance - - request = TableExistsRequest(id=["test_db", "test_table"]) - hive_namespace.table_exists(request) - - mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - - def test_drop_table_not_supported(self, hive_namespace, mock_hive_client): - """Test that drop_table raises NotImplementedError.""" - request = DropTableRequest(id=["test_db", "test_table"]) - - with pytest.raises(NotImplementedError, match="drop_table is not supported"): - hive_namespace.drop_table(request) - def test_deregister_table(self, hive_namespace, mock_hive_client): """Test deregistering a table without deleting data.""" mock_table = MagicMock() @@ -451,10 +267,6 @@ def test_get_table_location(self, hive_namespace): def test_root_namespace_operations(self, hive_namespace): """Test root namespace operations.""" - # Test namespace_exists for root - request = NamespaceExistsRequest(id=[]) - hive_namespace.namespace_exists(request) # Should not raise - # Test describe_namespace for root request = DescribeNamespaceRequest(id=[]) response = hive_namespace.describe_namespace(request) diff --git a/python/tests/test_hive3.py b/python/tests/test_hive3.py index b620efe..9291ffa 100644 --- a/python/tests/test_hive3.py +++ b/python/tests/test_hive3.py @@ -2,11 +2,8 @@ Tests for Lance Hive3 Namespace implementation. """ -import os import pytest -import tempfile from unittest.mock import MagicMock, patch -import pyarrow as pa from lance_namespace_impls.hive3 import Hive3Namespace from lance_namespace_urllib3_client.models import ( @@ -14,13 +11,9 @@ DescribeNamespaceRequest, CreateNamespaceRequest, DropNamespaceRequest, - NamespaceExistsRequest, ListTablesRequest, DescribeTableRequest, - RegisterTableRequest, DeregisterTableRequest, - TableExistsRequest, - DropTableRequest, ) @@ -166,16 +159,6 @@ def test_drop_namespace_database(self, hive_namespace, mock_hive_client): "test_db", deleteData=True, cascade=False ) - def test_namespace_exists_database(self, hive_namespace, mock_hive_client): - """Test checking if a database namespace exists.""" - mock_client_instance = MagicMock() - mock_hive_client.__enter__.return_value = mock_client_instance - - request = NamespaceExistsRequest(id=["hive", "test_db"]) - hive_namespace.namespace_exists(request) - - mock_client_instance.get_database.assert_called_once_with("test_db") - def test_list_tables(self, hive_namespace, mock_hive_client): """Test listing tables in a database.""" mock_table1 = MagicMock() @@ -235,79 +218,6 @@ def test_describe_table(self, hive_namespace, mock_hive_client): mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - def test_register_table(self, hive_namespace, mock_hive_client): - """Test registering a Lance table with 3-level identifier.""" - with tempfile.TemporaryDirectory() as tmpdir: - table_path = os.path.join(tmpdir, "test_table") - - data = pa.table({"id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"]}) - - with patch( - "lance_namespace_impls.hive3.lance.dataset" - ) as mock_dataset_func: - mock_dataset = MagicMock() - mock_dataset.schema = data.schema - mock_dataset.version = 1 - mock_dataset_func.return_value = mock_dataset - - mock_client_instance = MagicMock() - mock_hive_client.__enter__.return_value = mock_client_instance - - with ( - patch( - "lance_namespace_impls.hive3.HiveTable" - ) as mock_hive_table_class, - patch( - "lance_namespace_impls.hive3.StorageDescriptor" - ) as mock_sd_class, - patch("lance_namespace_impls.hive3.SerDeInfo") as mock_serde_class, - patch( - "lance_namespace_impls.hive3.FieldSchema" - ) as mock_field_class, - ): - mock_hive_table = MagicMock() - mock_hive_table_class.return_value = mock_hive_table - mock_sd = MagicMock() - mock_sd_class.return_value = mock_sd - mock_serde = MagicMock() - mock_serde_class.return_value = mock_serde - mock_field_class.return_value = MagicMock() - - request = RegisterTableRequest( - id=["hive", "test_db", "test_table"], - location=table_path, - properties={"owner": "test_user"}, - ) - response = hive_namespace.register_table(request) - - assert response.location == table_path - mock_client_instance.create_table.assert_called_once_with( - mock_hive_table - ) - assert mock_hive_table.dbName == "test_db" - assert mock_hive_table.tableName == "test_table" - - def test_table_exists(self, hive_namespace, mock_hive_client): - """Test checking if a table exists with 3-level identifier.""" - mock_table = MagicMock() - mock_table.parameters = {"table_type": "lance"} - - mock_client_instance = MagicMock() - mock_client_instance.get_table.return_value = mock_table - mock_hive_client.__enter__.return_value = mock_client_instance - - request = TableExistsRequest(id=["hive", "test_db", "test_table"]) - hive_namespace.table_exists(request) - - mock_client_instance.get_table.assert_called_once_with("test_db", "test_table") - - def test_drop_table_not_supported(self, hive_namespace, mock_hive_client): - """Test that drop_table raises NotImplementedError.""" - request = DropTableRequest(id=["hive", "test_db", "test_table"]) - - with pytest.raises(NotImplementedError, match="drop_table is not supported"): - hive_namespace.drop_table(request) - def test_deregister_table(self, hive_namespace, mock_hive_client): """Test deregistering a table with 3-level identifier.""" mock_table = MagicMock() @@ -358,10 +268,6 @@ def test_get_table_location(self, hive_namespace): def test_root_namespace_operations(self, hive_namespace): """Test root namespace operations.""" - # namespace_exists for root should not raise - request = NamespaceExistsRequest(id=[]) - hive_namespace.namespace_exists(request) - # describe_namespace for root request = DescribeNamespaceRequest(id=[]) response = hive_namespace.describe_namespace(request) diff --git a/python/tests/test_unity.py b/python/tests/test_unity.py index 3057679..4a9f5e0 100644 --- a/python/tests/test_unity.py +++ b/python/tests/test_unity.py @@ -23,10 +23,8 @@ DescribeNamespaceRequest, DropNamespaceRequest, ListTablesRequest, - CreateTableRequest, CreateEmptyTableRequest, DescribeTableRequest, - DropTableRequest, ) @@ -303,22 +301,6 @@ def test_list_tables(self, mock_rest_client_class): # Should only return Lance tables self.assertEqual(sorted(response.tables), ["table1", "table3"]) - @patch("lance_namespace_impls.unity.RestClient") - def test_create_table_not_supported(self, mock_rest_client_class): - """Test that create_table raises NotImplementedError.""" - mock_client = MagicMock() - mock_rest_client_class.return_value = mock_client - - namespace = UnityNamespace(**self.properties) - - request = CreateTableRequest() - request.id = ["test_catalog", "test_schema", "test_table"] - - with self.assertRaises(NotImplementedError) as context: - namespace.create_table(request, b"test_data") - - self.assertIn("create_table is not supported", str(context.exception)) - @patch("lance_namespace_impls.unity.RestClient") def test_create_empty_table(self, mock_rest_client_class): """Test creating an empty table.""" @@ -377,22 +359,6 @@ def test_describe_table(self, mock_rest_client_class): response.location, "/data/lance/test_catalog/test_schema/test_table" ) - @patch("lance_namespace_impls.unity.RestClient") - def test_drop_table_not_supported(self, mock_rest_client_class): - """Test that drop_table raises NotImplementedError.""" - mock_client = MagicMock() - mock_rest_client_class.return_value = mock_client - - namespace = UnityNamespace(**self.properties) - - request = DropTableRequest() - request.id = ["test_catalog", "test_schema", "test_table"] - - with self.assertRaises(NotImplementedError) as context: - namespace.drop_table(request) - - self.assertIn("drop_table is not supported", str(context.exception)) - def test_arrow_type_conversion(self): """Test Arrow type to Unity type conversion.""" namespace = UnityNamespace(**self.properties) From 937da0363a0ca9fbebd0bc37800e256e86136f0c Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:14:32 -0800 Subject: [PATCH 14/20] java: add basic operations restrictions and update namespace version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add CASCADE behavior rejection to dropNamespace for all implementations - Add load_detailed_metadata=true rejection to describeTable for all implementations - Update lance-namespace version to 0.4.2 - Rename createEmptyTable to declareTable for Iceberg - Update tests to expect InvalidInputException for CASCADE behavior - Remove non-basic operation tests from test files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/src/iceberg.md | 33 ++++++-------- .../namespace/glue/TestGlueNamespace.java | 26 ++--------- .../lance/namespace/hive2/Hive2Namespace.java | 9 ++++ .../hive2/TestHive2NamespaceIntegration.java | 28 +++--------- .../lance/namespace/hive3/Hive3Namespace.java | 9 ++++ .../namespace/hive3/TestHive3Namespace.java | 29 +++---------- .../hive3/TestHive3NamespaceIntegration.java | 28 +++--------- .../namespace/iceberg/IcebergNamespace.java | 43 +++++++++++++++---- .../iceberg/IcebergNamespaceConfig.java | 15 ------- .../namespace/polaris/PolarisNamespace.java | 9 ++++ .../lance/namespace/unity/UnityNamespace.java | 9 ++++ .../namespace/unity/TestUnityNamespace.java | 2 +- .../unity/TestUnityNamespaceIntegration.java | 28 +++--------- java/pom.xml | 2 +- 14 files changed, 115 insertions(+), 155 deletions(-) diff --git a/docs/src/iceberg.md b/docs/src/iceberg.md index 734684e..9550ee5 100644 --- a/docs/src/iceberg.md +++ b/docs/src/iceberg.md @@ -10,23 +10,16 @@ Apache Iceberg REST Catalog is a standardized REST API for interacting with Iceb The Lance Iceberg REST Catalog namespace implementation accepts the following configuration properties: -The **endpoint** property is required and specifies the Iceberg REST Catalog server endpoint URL (e.g., `http://localhost:8181`). Must start with `http://` or `https://`. - -The **warehouse** property is optional and specifies the warehouse identifier to use. Some Iceberg REST implementations require this. - -The **prefix** property is optional and specifies the API path prefix (e.g., `v1`). Default value is empty. - -The **auth_token** property is optional and specifies the bearer token for authentication. - -The **credential** property is optional and specifies the OAuth2 client credential in the format `client_id:client_secret` for client credentials authentication flow. - -The **connect_timeout** property is optional and specifies the connection timeout in milliseconds. Default value is `10000` (10 seconds). - -The **read_timeout** property is optional and specifies the read timeout in milliseconds. Default value is `30000` (30 seconds). - -The **max_retries** property is optional and specifies the maximum number of retries for failed requests. Default value is `3`. - -The **root** property is optional and specifies the default storage root location for tables. Default value is the current working directory. +| Property | Required | Default | Description | +|----------|----------|---------|-------------| +| `endpoint` | Yes | - | Iceberg REST Catalog server endpoint URL (e.g., `http://localhost:8181`). Must start with `http://` or `https://`. | +| `warehouse` | No | - | Warehouse identifier. Some Iceberg REST implementations require this. The warehouse name is resolved to an API prefix via the `/v1/config` endpoint. | +| `auth_token` | No | - | Bearer token for authentication. | +| `credential` | No | - | OAuth2 client credential in `client_id:client_secret` format for client credentials authentication flow. | +| `connect_timeout` | No | `10000` | Connection timeout in milliseconds. | +| `read_timeout` | No | `30000` | Read timeout in milliseconds. | +| `max_retries` | No | `3` | Maximum number of retries for failed requests. | +| `root` | No | current working directory | Default storage root location for tables. | ## Object Mapping @@ -110,7 +103,7 @@ The implementation: **Error Handling:** -If the namespace does not exist, return error code `1` (NamespaceNotFound). +If the namespace does not exist, the operation succeeds (idempotent behavior). If the namespace is not empty, return error code `3` (NamespaceNotEmpty). @@ -125,11 +118,11 @@ The implementation: 1. Parse the table identifier to extract namespace and table name 2. Construct a CreateTableRequest with: - `name`: the table name - - `location`: the specified or default location + - `location`: the specified or default location (defaults to `{root}/{prefix}/{namespace}/{table_name}`) - `schema`: a dummy Iceberg schema with a single nullable string column `dummy` - `properties`: table properties including `table_type=lance` 3. POST to `/v1/{prefix}/namespaces/{namespace}/tables` -4. Return the created table location and properties +4. Return the declared table location **Error Handling:** diff --git a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java index 1e43474..ca9f69d 100644 --- a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java +++ b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java @@ -13,6 +13,7 @@ */ package org.lance.namespace.glue; +import org.lance.namespace.errors.InvalidInputException; import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; @@ -79,7 +80,6 @@ import static org.lance.namespace.glue.GlueNamespace.TABLE_TYPE_PROP; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -443,7 +443,7 @@ public void testDropNamespaceWithRestrictBehaviorHasTables() { } @Test - public void testDropNamespaceWithCascadeBehaviorHasTables() { + public void testDropNamespaceWithCascadeBehaviorRejected() { String namespaceName = "ns1"; DropNamespaceRequest request = new DropNamespaceRequest() @@ -451,26 +451,8 @@ public void testDropNamespaceWithCascadeBehaviorHasTables() { .mode("Fail") .behavior("Cascade"); - Database database = Database.builder().name(namespaceName).build(); - Table table1 = Table.builder().name("table1").build(); - Table table2 = Table.builder().name("table2").build(); - - // Mock database call - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenReturn(GetDatabaseResponse.builder().database(database).build()); - - // Mock get tables for cascade - when(glue.getTables(any(GetTablesRequest.class))) - .thenReturn(GetTablesResponse.builder().tableList(table1, table2).build()); - - when(glue.deleteDatabase(any(DeleteDatabaseRequest.class))) - .thenReturn(DeleteDatabaseResponse.builder().build()); - - glueNamespace.dropNamespace(request); - - verify(glue).getTables(any(GetTablesRequest.class)); - verify(glue, times(2)).deleteTable(any(DeleteTableRequest.class)); - verify(glue).deleteDatabase(any(DeleteDatabaseRequest.class)); + // CASCADE behavior should be rejected + assertThrows(InvalidInputException.class, () -> glueNamespace.dropNamespace(request)); } @Test diff --git a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java index fc94416..7c07ac2 100644 --- a/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java +++ b/java/lance-namespace-hive2/src/main/java/org/lance/namespace/hive2/Hive2Namespace.java @@ -203,6 +203,10 @@ public DescribeNamespaceResponse describeNamespace(DescribeNamespaceRequest requ @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + ObjectIdentifier id = ObjectIdentifier.of(request.getId()); String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; String behavior = request.getBehavior() != null ? request.getBehavior() : "Restrict"; @@ -262,6 +266,11 @@ public void tableExists(TableExistsRequest request) { @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( diff --git a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java index 0d5926a..e6ba013 100644 --- a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java +++ b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java @@ -13,6 +13,7 @@ */ package org.lance.namespace.hive2; +import org.lance.namespace.errors.InvalidInputException; import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; @@ -114,7 +115,7 @@ public void tearDown() { // Clean up test database DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Collections.singletonList(testDatabase)); - dropRequest.setBehavior("Cascade"); + dropRequest.setBehavior("Restrict"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors @@ -220,29 +221,14 @@ public void testTableOperations() { } @Test - public void testCascadeDropDatabase() { - // Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Collections.singletonList(testDatabase)); - namespace.createNamespace(nsRequest); - - // Create a table in the database - String tableName = "cascade_test_table"; - CreateEmptyTableRequest tableRequest = new CreateEmptyTableRequest(); - tableRequest.setId(Arrays.asList(testDatabase, tableName)); - tableRequest.setLocation("/tmp/lance-integration-test/" + testDatabase + "/" + tableName); - namespace.createEmptyTable(tableRequest); - - // Drop database with cascade + public void testCascadeDropDatabaseRejected() { + // Drop database with cascade - should be rejected DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Collections.singletonList(testDatabase)); dropRequest.setBehavior("Cascade"); - namespace.dropNamespace(dropRequest); - // Verify database doesn't exist - DescribeNamespaceRequest describeRequest = new DescribeNamespaceRequest(); - describeRequest.setId(Collections.singletonList(testDatabase)); - assertThatThrownBy(() -> namespace.describeNamespace(describeRequest)) - .isInstanceOf(LanceNamespaceException.class); + assertThatThrownBy(() -> namespace.dropNamespace(dropRequest)) + .isInstanceOf(InvalidInputException.class) + .hasMessageContaining("Cascade behavior is not supported"); } } diff --git a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java index e53fe6d..258332a 100644 --- a/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java +++ b/java/lance-namespace-hive3/src/main/java/org/lance/namespace/hive3/Hive3Namespace.java @@ -220,6 +220,10 @@ public void namespaceExists(NamespaceExistsRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + ObjectIdentifier id = ObjectIdentifier.of(request.getId()); String mode = request.getMode() != null ? request.getMode().toLowerCase() : "fail"; String behavior = request.getBehavior() != null ? request.getBehavior() : "Restrict"; @@ -279,6 +283,11 @@ public ListTablesResponse listTables(ListTablesRequest request) { @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( diff --git a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java index 42724d4..e98376a 100644 --- a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java +++ b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3Namespace.java @@ -14,6 +14,7 @@ package org.lance.namespace.hive3; import org.lance.namespace.LanceNamespace; +import org.lance.namespace.errors.InvalidInputException; import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceRequest; @@ -327,35 +328,15 @@ public void testDropNamespaceBasicDatabase() throws IOException { } @Test - public void testDropNamespaceBasicCatalog() { - // Setup: Create catalog - CreateNamespaceRequest catalogRequest = new CreateNamespaceRequest(); - catalogRequest.setId(Lists.list("test_catalog_basic")); - catalogRequest.setMode("Create"); - - Map properties = Maps.newHashMap(); - properties.put("description", "Test catalog for dropping"); - catalogRequest.setProperties(properties); - - namespace.createNamespace(catalogRequest); - - // Test: Drop the catalog with CASCADE (since Hive creates default database automatically) + public void testDropNamespaceCascadeRejected() { + // Test: Drop with CASCADE behavior - should be rejected DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Lists.list("test_catalog_basic")); dropRequest.setBehavior("Cascade"); - DropNamespaceResponse response = namespace.dropNamespace(dropRequest); - - // Verify properties were returned - assertEquals("Test catalog for dropping", response.getProperties().get("description")); - - // Verify catalog was dropped - NamespaceExistsRequest existsRequest = new NamespaceExistsRequest(); - existsRequest.setId(Lists.list("test_catalog_basic")); - Exception error = - assertThrows(LanceNamespaceException.class, () -> namespace.namespaceExists(existsRequest)); - assertTrue(error.getMessage().contains("Namespace does not exist")); + assertThrows(InvalidInputException.class, () -> namespace.dropNamespace(dropRequest)); + assertTrue(error.getMessage().contains("Cascade behavior is not supported")); } @Test diff --git a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java index 50ab8b2..8e26396 100644 --- a/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java +++ b/java/lance-namespace-hive3/src/test/java/org/lance/namespace/hive3/TestHive3NamespaceIntegration.java @@ -13,6 +13,7 @@ */ package org.lance.namespace.hive3; +import org.lance.namespace.errors.InvalidInputException; import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; @@ -116,7 +117,7 @@ public void tearDown() { // Clean up test database DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(testCatalog, testDatabase)); - dropRequest.setBehavior("Cascade"); + dropRequest.setBehavior("Restrict"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors @@ -220,29 +221,14 @@ public void testTableOperations() { } @Test - public void testCascadeDropDatabase() { - // Create database - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Arrays.asList(testCatalog, testDatabase)); - namespace.createNamespace(nsRequest); - - // Create a table in the database - String tableName = "cascade_test_table"; - CreateEmptyTableRequest tableRequest = new CreateEmptyTableRequest(); - tableRequest.setId(Arrays.asList(testCatalog, testDatabase, tableName)); - tableRequest.setLocation("/tmp/lance-integration-test/" + testDatabase + "/" + tableName); - namespace.createEmptyTable(tableRequest); - - // Drop database with cascade + public void testCascadeDropDatabaseRejected() { + // Drop database with cascade - should be rejected DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(testCatalog, testDatabase)); dropRequest.setBehavior("Cascade"); - namespace.dropNamespace(dropRequest); - // Verify database doesn't exist - DescribeNamespaceRequest describeRequest = new DescribeNamespaceRequest(); - describeRequest.setId(Arrays.asList(testCatalog, testDatabase)); - assertThatThrownBy(() -> namespace.describeNamespace(describeRequest)) - .isInstanceOf(LanceNamespaceException.class); + assertThatThrownBy(() -> namespace.dropNamespace(dropRequest)) + .isInstanceOf(InvalidInputException.class) + .hasMessageContaining("Cascade behavior is not supported"); } } diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java index 5a76aa6..9eb2050 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespace.java @@ -24,6 +24,8 @@ import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeclareTableRequest; +import org.lance.namespace.model.DeclareTableResponse; import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DeregisterTableResponse; import org.lance.namespace.model.DescribeNamespaceRequest; @@ -272,6 +274,10 @@ public void namespaceExists(NamespaceExistsRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( nsId.levels() >= 2, "Namespace must have at least prefix and namespace levels"); @@ -343,7 +349,7 @@ public ListTablesResponse listTables(ListTablesRequest request) { } @Override - public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { + public DeclareTableResponse declareTable(DeclareTableRequest request) { ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() >= 3, "Table identifier must have prefix, namespace, and table name"); @@ -371,15 +377,14 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request createRequest.setProperties(properties); String namespacePath = encodeNamespace(namespace); - IcebergModels.LoadTableResponse response = - restClient.post( - prefixPath + "/namespaces/" + namespacePath + "/tables", - createRequest, - IcebergModels.LoadTableResponse.class); + restClient.post( + prefixPath + "/namespaces/" + namespacePath + "/tables", + createRequest, + IcebergModels.LoadTableResponse.class); - LOG.info("Created Lance table: {}", tableId.stringStyleId()); + LOG.info("Declared Lance table: {}", tableId.stringStyleId()); - CreateEmptyTableResponse result = new CreateEmptyTableResponse(); + DeclareTableResponse result = new DeclareTableResponse(); result.setLocation(tablePath); return result; } catch (RestClientException e) { @@ -390,12 +395,32 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request throw new NamespaceNotFoundException( "Namespace not found: " + prefix + "." + String.join(".", namespace)); } - throw new InternalException("Failed to create table: " + e.getMessage()); + throw new InternalException("Failed to declare table: " + e.getMessage()); } } + /** + * @deprecated Use {@link #declareTable(DeclareTableRequest)} instead. + */ + @Deprecated + @Override + public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request) { + DeclareTableRequest declareRequest = new DeclareTableRequest(); + declareRequest.setId(request.getId()); + declareRequest.setLocation(request.getLocation()); + DeclareTableResponse response = declareTable(declareRequest); + CreateEmptyTableResponse result = new CreateEmptyTableResponse(); + result.setLocation(response.getLocation()); + return result; + } + @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() >= 3, "Table identifier must have prefix, namespace, and table name"); diff --git a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java index 438fa5c..ce1793c 100644 --- a/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java +++ b/java/lance-namespace-iceberg/src/main/java/org/lance/namespace/iceberg/IcebergNamespaceConfig.java @@ -20,7 +20,6 @@ public class IcebergNamespaceConfig { public static final String ENDPOINT = "endpoint"; public static final String WAREHOUSE = "warehouse"; - public static final String PREFIX = "prefix"; public static final String AUTH_TOKEN = "auth_token"; public static final String CREDENTIAL = "credential"; public static final String CONNECT_TIMEOUT = "connect_timeout"; @@ -30,7 +29,6 @@ public class IcebergNamespaceConfig { private final String endpoint; private final String warehouse; - private final String prefix; private final String authToken; private final String credential; private final int connectTimeout; @@ -45,7 +43,6 @@ public IcebergNamespaceConfig(Map properties) { } this.warehouse = properties.get(WAREHOUSE); - this.prefix = properties.getOrDefault(PREFIX, ""); this.authToken = properties.get(AUTH_TOKEN); this.credential = properties.get(CREDENTIAL); this.connectTimeout = Integer.parseInt(properties.getOrDefault(CONNECT_TIMEOUT, "10000")); @@ -62,10 +59,6 @@ public String getWarehouse() { return warehouse; } - public String getPrefix() { - return prefix; - } - public String getAuthToken() { return authToken; } @@ -90,14 +83,6 @@ public String getRoot() { return root; } - public String getFullApiUrl() { - String base = endpoint.endsWith("/") ? endpoint.substring(0, endpoint.length() - 1) : endpoint; - if (prefix != null && !prefix.isEmpty()) { - return base + "/" + prefix; - } - return base; - } - public String getBaseApiUrl() { return endpoint.endsWith("/") ? endpoint.substring(0, endpoint.length() - 1) : endpoint; } diff --git a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java index 88530f4..b70461a 100644 --- a/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java +++ b/java/lance-namespace-polaris/src/main/java/org/lance/namespace/polaris/PolarisNamespace.java @@ -197,6 +197,10 @@ public ListNamespacesResponse listNamespaces(ListNamespacesRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + ObjectIdentifier namespaceId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( namespaceId.levels() >= 2, "Namespace must have at least catalog and namespace levels"); @@ -311,6 +315,11 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() >= 3, "Table identifier must have catalog, namespace, and table name"); diff --git a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java index 4d6eee7..227a5db 100644 --- a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java +++ b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java @@ -229,6 +229,10 @@ public void namespaceExists(NamespaceExistsRequest request) { @Override public DropNamespaceResponse dropNamespace(DropNamespaceRequest request) { + if ("Cascade".equalsIgnoreCase(request.getBehavior())) { + throw new InvalidInputException("Cascade behavior is not supported for this implementation"); + } + ObjectIdentifier nsId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument(nsId.levels() == 2, "Expect a 2-level namespace but get %s", nsId); @@ -363,6 +367,11 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request @Override public DescribeTableResponse describeTable(DescribeTableRequest request) { + if (Boolean.TRUE.equals(request.getLoadDetailedMetadata())) { + throw new InvalidInputException( + "load_detailed_metadata=true is not supported for this implementation"); + } + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); ValidationUtil.checkArgument( tableId.levels() == 3, "Expect a 3-level table identifier but get %s", tableId); diff --git a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java index 96f6a4c..b935abb 100644 --- a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java +++ b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespace.java @@ -139,7 +139,7 @@ public void tearDown() throws IOException { try { DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(UNITY_CATALOG, TEST_SCHEMA)); - dropRequest.setBehavior("Cascade"); + dropRequest.setBehavior("Restrict"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors diff --git a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java index f470e0d..21033ae 100644 --- a/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java +++ b/java/lance-namespace-unity/src/test/java/org/lance/namespace/unity/TestUnityNamespaceIntegration.java @@ -13,6 +13,7 @@ */ package org.lance.namespace.unity; +import org.lance.namespace.errors.InvalidInputException; import org.lance.namespace.errors.LanceNamespaceException; import org.lance.namespace.model.CreateEmptyTableRequest; import org.lance.namespace.model.CreateEmptyTableResponse; @@ -161,7 +162,7 @@ public void tearDown() { // Clean up test schema DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); - dropRequest.setBehavior("Cascade"); + dropRequest.setBehavior("Restrict"); namespace.dropNamespace(dropRequest); } catch (Exception e) { // Ignore cleanup errors @@ -268,29 +269,14 @@ public void testTableOperations() { } @Test - public void testCascadeDropSchema() { - // Create schema - CreateNamespaceRequest nsRequest = new CreateNamespaceRequest(); - nsRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); - namespace.createNamespace(nsRequest); - - // Create a table in the schema - String tableName = "cascade_test_table"; - CreateEmptyTableRequest tableRequest = new CreateEmptyTableRequest(); - tableRequest.setId(Arrays.asList(TEST_CATALOG, testSchema, tableName)); - tableRequest.setLocation("/tmp/lance-integration-test/" + testSchema + "/" + tableName); - namespace.createEmptyTable(tableRequest); - - // Drop schema with cascade + public void testCascadeDropSchemaRejected() { + // Drop schema with cascade - should be rejected DropNamespaceRequest dropRequest = new DropNamespaceRequest(); dropRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); dropRequest.setBehavior("Cascade"); - namespace.dropNamespace(dropRequest); - // Verify schema doesn't exist - DescribeNamespaceRequest describeRequest = new DescribeNamespaceRequest(); - describeRequest.setId(Arrays.asList(TEST_CATALOG, testSchema)); - assertThatThrownBy(() -> namespace.describeNamespace(describeRequest)) - .isInstanceOf(LanceNamespaceException.class); + assertThatThrownBy(() -> namespace.dropNamespace(dropRequest)) + .isInstanceOf(InvalidInputException.class) + .hasMessageContaining("Cascade behavior is not supported"); } } diff --git a/java/pom.xml b/java/pom.xml index b8f603e..7e57514 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -58,7 +58,7 @@ UTF-8 2.0.0-beta.4 - 0.4.0 + 0.4.2 15.0.0 5.8.2 From e49c388a2c6063f032bcba3307429bf9d562cdd5 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 01:23:24 -0800 Subject: [PATCH 15/20] test: remove non-basic operation tests from integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove namespace_exists, table_exists, and register_table tests from all integration test files to align with the basic operations specification (ListNamespaces, CreateNamespace, DescribeNamespace, DropNamespace, ListTables, DeclareTable, DescribeTable, DeregisterTable). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- python/tests/test_glue_integration.py | 53 +----------------------- python/tests/test_hive2_integration.py | 22 +--------- python/tests/test_hive3_integration.py | 22 +--------- python/tests/test_iceberg_integration.py | 26 +----------- python/tests/test_polaris_integration.py | 26 +----------- python/tests/test_unity_integration.py | 26 +----------- 6 files changed, 6 insertions(+), 169 deletions(-) diff --git a/python/tests/test_glue_integration.py b/python/tests/test_glue_integration.py index defbd1e..5f3569f 100644 --- a/python/tests/test_glue_integration.py +++ b/python/tests/test_glue_integration.py @@ -131,7 +131,6 @@ def test_namespace_operations(self): DescribeNamespaceRequest, DropNamespaceRequest, ListNamespacesRequest, - NamespaceExistsRequest, ) db_name = f"lance_test_{uuid.uuid4().hex[:8]}" @@ -153,10 +152,6 @@ def test_namespace_operations(self): describe_response.properties.get("description"), "Test database for Lance" ) - exists_request = NamespaceExistsRequest() - exists_request.id = [db_name] - self.namespace.namespace_exists(exists_request) - list_request = ListNamespacesRequest() list_request.id = [] list_response = self.namespace.list_namespaces(list_request) @@ -167,9 +162,6 @@ def test_namespace_operations(self): self.namespace.drop_namespace(drop_request) self.created_databases.remove(db_name) - with self.assertRaises(RuntimeError): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" from lance_namespace_urllib3_client.models import ( @@ -177,13 +169,13 @@ def test_table_operations(self): DescribeTableRequest, DeregisterTableRequest, ListTablesRequest, - TableExistsRequest, ) db_name = self._create_test_database() table_name = f"test_table_{uuid.uuid4().hex[:8]}" table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [db_name, table_name] create_request.location = table_location @@ -199,10 +191,6 @@ def test_table_operations(self): self.assertIsNotNone(describe_response.location) self.assertEqual(describe_response.location, table_location) - exists_request = TableExistsRequest() - exists_request.id = [db_name, table_name] - self.namespace.table_exists(exists_request) - list_request = ListTablesRequest() list_request.id = [db_name] @@ -213,45 +201,6 @@ def test_table_operations(self): deregister_request.id = [db_name, table_name] self.namespace.deregister_table(deregister_request) - with self.assertRaises(RuntimeError): - self.namespace.table_exists(exists_request) - - def test_register_existing_table(self): - """Test registering an existing Lance table.""" - import lance - import pyarrow as pa - from lance_namespace_urllib3_client.models import ( - DescribeTableRequest, - DeregisterTableRequest, - RegisterTableRequest, - ) - - db_name = self._create_test_database() - table_name = f"existing_table_{uuid.uuid4().hex[:8]}" - table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") - - os.makedirs(os.path.dirname(table_location), exist_ok=True) - table = pa.table({"id": [1, 2, 3], "name": ["a", "b", "c"]}) - lance.write_dataset(table, table_location) - - register_request = RegisterTableRequest() - register_request.id = [db_name, table_name] - register_request.location = table_location - - register_response = self.namespace.register_table(register_request) - self.assertIsNotNone(register_response.location) - self.assertEqual(register_response.location, table_location) - - describe_request = DescribeTableRequest() - describe_request.id = [db_name, table_name] - - describe_response = self.namespace.describe_table(describe_request) - self.assertEqual(describe_response.location, table_location) - - deregister_request = DeregisterTableRequest() - deregister_request.id = [db_name, table_name] - self.namespace.deregister_table(deregister_request) - def test_multiple_tables_in_namespace(self): """Test creating and listing multiple tables in a namespace.""" from lance_namespace_urllib3_client.models import ( diff --git a/python/tests/test_hive2_integration.py b/python/tests/test_hive2_integration.py index 8223855..216d713 100644 --- a/python/tests/test_hive2_integration.py +++ b/python/tests/test_hive2_integration.py @@ -24,8 +24,6 @@ DropNamespaceRequest, ListNamespacesRequest, ListTablesRequest, - NamespaceExistsRequest, - TableExistsRequest, ) @@ -110,11 +108,6 @@ def test_namespace_operations(self): "Test database for integration tests", ) - # Check namespace exists - exists_request = NamespaceExistsRequest() - exists_request.id = [self.test_database] - self.namespace.namespace_exists(exists_request) # Should not throw - # List namespaces (databases) list_request = ListNamespacesRequest() list_request.id = [] @@ -126,10 +119,6 @@ def test_namespace_operations(self): drop_request.id = [self.test_database] self.namespace.drop_namespace(drop_request) - # Verify namespace doesn't exist - with self.assertRaises(ValueError): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" # Create namespace first @@ -139,7 +128,7 @@ def test_table_operations(self): table_name = f"test_table_{uuid.uuid4().hex[:8]}" - # Create empty table + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [self.test_database, table_name] create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" @@ -154,11 +143,6 @@ def test_table_operations(self): describe_response = self.namespace.describe_table(describe_request) self.assertIsNotNone(describe_response.location) - # Check table exists - exists_request = TableExistsRequest() - exists_request.id = [self.test_database, table_name] - self.namespace.table_exists(exists_request) # Should not throw - # List tables list_request = ListTablesRequest() list_request.id = [self.test_database] @@ -171,10 +155,6 @@ def test_table_operations(self): deregister_request.id = [self.test_database, table_name] self.namespace.deregister_table(deregister_request) - # Verify table doesn't exist - with self.assertRaises(ValueError): - self.namespace.table_exists(exists_request) - def test_create_empty_table_with_location(self): """Test creating an empty table with a specific location.""" # Create namespace first diff --git a/python/tests/test_hive3_integration.py b/python/tests/test_hive3_integration.py index 552d677..80ac949 100644 --- a/python/tests/test_hive3_integration.py +++ b/python/tests/test_hive3_integration.py @@ -24,8 +24,6 @@ DropNamespaceRequest, ListNamespacesRequest, ListTablesRequest, - NamespaceExistsRequest, - TableExistsRequest, ) @@ -124,11 +122,6 @@ def test_namespace_operations(self): "Test database for integration tests", ) - # Check namespace exists - exists_request = NamespaceExistsRequest() - exists_request.id = [self.test_catalog, self.test_database] - self.namespace.namespace_exists(exists_request) # Should not throw - # List namespaces (databases) list_request = ListNamespacesRequest() list_request.id = [self.test_catalog] @@ -140,10 +133,6 @@ def test_namespace_operations(self): drop_request.id = [self.test_catalog, self.test_database] self.namespace.drop_namespace(drop_request) - # Verify namespace doesn't exist - with self.assertRaises(ValueError): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" # Create namespace first @@ -153,7 +142,7 @@ def test_table_operations(self): table_name = f"test_table_{uuid.uuid4().hex[:8]}" - # Create empty table + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [self.test_catalog, self.test_database, table_name] create_request.location = f"/tmp/lance/{self.test_database}/{table_name}" @@ -168,11 +157,6 @@ def test_table_operations(self): describe_response = self.namespace.describe_table(describe_request) self.assertIsNotNone(describe_response.location) - # Check table exists - exists_request = TableExistsRequest() - exists_request.id = [self.test_catalog, self.test_database, table_name] - self.namespace.table_exists(exists_request) # Should not throw - # List tables list_request = ListTablesRequest() list_request.id = [self.test_catalog, self.test_database] @@ -185,10 +169,6 @@ def test_table_operations(self): deregister_request.id = [self.test_catalog, self.test_database, table_name] self.namespace.deregister_table(deregister_request) - # Verify table doesn't exist - with self.assertRaises(ValueError): - self.namespace.table_exists(exists_request) - def test_create_empty_table_with_location(self): """Test creating an empty table with a specific location.""" # Create namespace first diff --git a/python/tests/test_iceberg_integration.py b/python/tests/test_iceberg_integration.py index 53d5ed5..659e327 100644 --- a/python/tests/test_iceberg_integration.py +++ b/python/tests/test_iceberg_integration.py @@ -17,10 +17,6 @@ import pytest from lance_namespace_impls.iceberg import IcebergNamespace -from lance_namespace_impls.rest_client import ( - NamespaceNotFoundException, - TableNotFoundException, -) from lance_namespace_urllib3_client.models import ( CreateEmptyTableRequest, CreateNamespaceRequest, @@ -30,8 +26,6 @@ DropNamespaceRequest, ListNamespacesRequest, ListTablesRequest, - NamespaceExistsRequest, - TableExistsRequest, ) @@ -105,11 +99,6 @@ def test_namespace_operations(self): describe_response = self.namespace.describe_namespace(describe_request) self.assertIsNotNone(describe_response) - # Check namespace exists - exists_request = NamespaceExistsRequest() - exists_request.id = [self.test_warehouse, self.test_namespace] - self.namespace.namespace_exists(exists_request) - # List namespaces list_request = ListNamespacesRequest() list_request.id = [self.test_warehouse] @@ -122,10 +111,6 @@ def test_namespace_operations(self): drop_request.id = [self.test_warehouse, self.test_namespace] self.namespace.drop_namespace(drop_request) - # Verify namespace doesn't exist - with self.assertRaises(NamespaceNotFoundException): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" # Create namespace first @@ -135,7 +120,7 @@ def test_table_operations(self): table_name = f"test_table_{uuid.uuid4().hex[:8]}" - # Create empty table + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [self.test_warehouse, self.test_namespace, table_name] create_request.location = f"s3://warehouse/{self.test_namespace}/{table_name}" @@ -150,11 +135,6 @@ def test_table_operations(self): describe_response = self.namespace.describe_table(describe_request) self.assertIsNotNone(describe_response.location) - # Check table exists - exists_request = TableExistsRequest() - exists_request.id = [self.test_warehouse, self.test_namespace, table_name] - self.namespace.table_exists(exists_request) - # List tables list_request = ListTablesRequest() list_request.id = [self.test_warehouse, self.test_namespace] @@ -167,10 +147,6 @@ def test_table_operations(self): deregister_request.id = [self.test_warehouse, self.test_namespace, table_name] self.namespace.deregister_table(deregister_request) - # Verify table doesn't exist - with self.assertRaises(TableNotFoundException): - self.namespace.table_exists(exists_request) - def test_create_empty_table_with_location(self): """Test creating an empty table with a specific location.""" # Create namespace first diff --git a/python/tests/test_polaris_integration.py b/python/tests/test_polaris_integration.py index d266903..af35f06 100644 --- a/python/tests/test_polaris_integration.py +++ b/python/tests/test_polaris_integration.py @@ -16,10 +16,6 @@ import pytest from lance_namespace_impls.polaris import PolarisNamespace -from lance_namespace_impls.rest_client import ( - NamespaceNotFoundException, - TableNotFoundException, -) from lance_namespace_urllib3_client.models import ( CreateEmptyTableRequest, CreateNamespaceRequest, @@ -29,8 +25,6 @@ DropNamespaceRequest, ListNamespacesRequest, ListTablesRequest, - NamespaceExistsRequest, - TableExistsRequest, ) @@ -137,11 +131,6 @@ def test_namespace_operations(self): describe_response = self.namespace.describe_namespace(describe_request) self.assertIsNotNone(describe_response) - # Check namespace exists - exists_request = NamespaceExistsRequest() - exists_request.id = [self.test_catalog, self.test_namespace] - self.namespace.namespace_exists(exists_request) # Should not throw - # List namespaces list_request = ListNamespacesRequest() list_request.id = [self.test_catalog] @@ -154,10 +143,6 @@ def test_namespace_operations(self): drop_request.id = [self.test_catalog, self.test_namespace] self.namespace.drop_namespace(drop_request) - # Verify namespace doesn't exist - with self.assertRaises(NamespaceNotFoundException): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" # Create namespace first @@ -167,7 +152,7 @@ def test_table_operations(self): table_name = f"test_table_{uuid.uuid4().hex[:8]}" - # Create empty table + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [self.test_catalog, self.test_namespace, table_name] create_request.location = f"/data/warehouse/{self.test_namespace}/{table_name}" @@ -182,11 +167,6 @@ def test_table_operations(self): describe_response = self.namespace.describe_table(describe_request) self.assertIsNotNone(describe_response.location) - # Check table exists - exists_request = TableExistsRequest() - exists_request.id = [self.test_catalog, self.test_namespace, table_name] - self.namespace.table_exists(exists_request) # Should not throw - # List tables list_request = ListTablesRequest() list_request.id = [self.test_catalog, self.test_namespace] @@ -199,10 +179,6 @@ def test_table_operations(self): deregister_request.id = [self.test_catalog, self.test_namespace, table_name] self.namespace.deregister_table(deregister_request) - # Verify table doesn't exist - with self.assertRaises(TableNotFoundException): - self.namespace.table_exists(exists_request) - def test_create_empty_table_with_location(self): """Test creating an empty table with a specific location.""" # Create namespace first diff --git a/python/tests/test_unity_integration.py b/python/tests/test_unity_integration.py index 0495be9..31f99c4 100644 --- a/python/tests/test_unity_integration.py +++ b/python/tests/test_unity_integration.py @@ -16,10 +16,6 @@ import pytest from lance_namespace_impls.unity import UnityNamespace -from lance_namespace_impls.rest_client import ( - NamespaceNotFoundException, - TableNotFoundException, -) from lance_namespace_urllib3_client.models import ( CreateEmptyTableRequest, CreateNamespaceRequest, @@ -29,8 +25,6 @@ DropNamespaceRequest, ListNamespacesRequest, ListTablesRequest, - NamespaceExistsRequest, - TableExistsRequest, ) @@ -133,11 +127,6 @@ def test_namespace_operations(self): describe_response = self.namespace.describe_namespace(describe_request) self.assertIsNotNone(describe_response) - # Check namespace exists - exists_request = NamespaceExistsRequest() - exists_request.id = [UNITY_CATALOG, self.test_schema] - self.namespace.namespace_exists(exists_request) # Should not throw - # List namespaces (schemas) list_request = ListNamespacesRequest() list_request.id = [UNITY_CATALOG] @@ -149,10 +138,6 @@ def test_namespace_operations(self): drop_request.id = [UNITY_CATALOG, self.test_schema] self.namespace.drop_namespace(drop_request) - # Verify namespace doesn't exist - with self.assertRaises(NamespaceNotFoundException): - self.namespace.namespace_exists(exists_request) - def test_table_operations(self): """Test table CRUD operations.""" # Create namespace first @@ -162,7 +147,7 @@ def test_table_operations(self): table_name = f"test_table_{uuid.uuid4().hex[:8]}" - # Create empty table + # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() create_request.id = [UNITY_CATALOG, self.test_schema, table_name] create_request.location = ( @@ -179,11 +164,6 @@ def test_table_operations(self): describe_response = self.namespace.describe_table(describe_request) self.assertIsNotNone(describe_response.location) - # Check table exists - exists_request = TableExistsRequest() - exists_request.id = [UNITY_CATALOG, self.test_schema, table_name] - self.namespace.table_exists(exists_request) # Should not throw - # List tables list_request = ListTablesRequest() list_request.id = [UNITY_CATALOG, self.test_schema] @@ -196,10 +176,6 @@ def test_table_operations(self): deregister_request.id = [UNITY_CATALOG, self.test_schema, table_name] self.namespace.deregister_table(deregister_request) - # Verify table doesn't exist - with self.assertRaises(TableNotFoundException): - self.namespace.table_exists(exists_request) - def test_create_empty_table_with_location(self): """Test creating an empty table with a specific location.""" # Create namespace first From a8d95df07520b8a662e6c4b9f17ced94317b92c4 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 08:25:08 -0800 Subject: [PATCH 16/20] chore: rename docker/lakekeeper to docker/iceberg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the directory to match the integration name while keeping the internal Lakekeeper container configuration unchanged. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/java-integ-iceberg.yml | 14 +++++++------- .github/workflows/python-integ-iceberg.yml | 14 +++++++------- docker/Makefile | 8 ++++---- docker/{lakekeeper => iceberg}/docker-compose.yml | 0 .../iceberg/TestIcebergNamespaceIntegration.java | 2 +- python/tests/test_iceberg_integration.py | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) rename docker/{lakekeeper => iceberg}/docker-compose.yml (100%) diff --git a/.github/workflows/java-integ-iceberg.yml b/.github/workflows/java-integ-iceberg.yml index e13625c..7a75d38 100644 --- a/.github/workflows/java-integ-iceberg.yml +++ b/.github/workflows/java-integ-iceberg.yml @@ -18,7 +18,7 @@ on: - main paths: - java/lance-namespace-iceberg/** - - docker/lakekeeper/** + - docker/iceberg/** - .github/workflows/java-integ-iceberg.yml pull_request: types: @@ -28,7 +28,7 @@ on: - reopened paths: - java/lance-namespace-iceberg/** - - docker/lakekeeper/** + - docker/iceberg/** - .github/workflows/java-integ-iceberg.yml workflow_dispatch: @@ -61,7 +61,7 @@ jobs: done ' || { echo "Timeout waiting for Iceberg REST Catalog" - docker compose -f docker/lakekeeper/docker-compose.yml logs + docker compose -f docker/iceberg/docker-compose.yml logs exit 1 } echo "Iceberg REST Catalog is ready" @@ -83,7 +83,7 @@ jobs: echo "test_warehouse verified" else echo "Warning: test_warehouse not found in warehouses: $WAREHOUSES" - docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper-setup + docker compose -f docker/iceberg/docker-compose.yml logs lakekeeper-setup fi - name: Build run: make build-java @@ -93,13 +93,13 @@ jobs: if: failure() run: | echo "=== Docker Compose Status ===" - docker compose -f docker/lakekeeper/docker-compose.yml ps + docker compose -f docker/iceberg/docker-compose.yml ps echo "" echo "=== Iceberg REST Catalog Logs ===" - docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper + docker compose -f docker/iceberg/docker-compose.yml logs lakekeeper echo "" echo "=== PostgreSQL Logs ===" - docker compose -f docker/lakekeeper/docker-compose.yml logs postgres-lakekeeper + docker compose -f docker/iceberg/docker-compose.yml logs postgres-lakekeeper - name: Cleanup if: always() run: make docker-down-iceberg diff --git a/.github/workflows/python-integ-iceberg.yml b/.github/workflows/python-integ-iceberg.yml index d6d8a3b..e551fdd 100644 --- a/.github/workflows/python-integ-iceberg.yml +++ b/.github/workflows/python-integ-iceberg.yml @@ -21,7 +21,7 @@ on: - python/src/lance_namespace_impls/rest_client.py - python/tests/test_iceberg.py - python/tests/test_iceberg_integration.py - - docker/lakekeeper/** + - docker/iceberg/** - .github/workflows/python-integ-iceberg.yml pull_request: types: @@ -34,7 +34,7 @@ on: - python/src/lance_namespace_impls/rest_client.py - python/tests/test_iceberg.py - python/tests/test_iceberg_integration.py - - docker/lakekeeper/** + - docker/iceberg/** - .github/workflows/python-integ-iceberg.yml workflow_dispatch: @@ -67,7 +67,7 @@ jobs: done ' || { echo "Timeout waiting for Iceberg REST Catalog" - docker compose -f docker/lakekeeper/docker-compose.yml logs + docker compose -f docker/iceberg/docker-compose.yml logs exit 1 } echo "Iceberg REST Catalog is ready" @@ -89,7 +89,7 @@ jobs: echo "test_warehouse verified" else echo "Warning: test_warehouse not found in warehouses: $WAREHOUSES" - docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper-setup + docker compose -f docker/iceberg/docker-compose.yml logs lakekeeper-setup fi - name: Install dependencies working-directory: python @@ -100,13 +100,13 @@ jobs: if: failure() run: | echo "=== Docker Compose Status ===" - docker compose -f docker/lakekeeper/docker-compose.yml ps + docker compose -f docker/iceberg/docker-compose.yml ps echo "" echo "=== Iceberg REST Catalog Logs ===" - docker compose -f docker/lakekeeper/docker-compose.yml logs lakekeeper + docker compose -f docker/iceberg/docker-compose.yml logs lakekeeper echo "" echo "=== PostgreSQL Logs ===" - docker compose -f docker/lakekeeper/docker-compose.yml logs postgres-lakekeeper + docker compose -f docker/iceberg/docker-compose.yml logs postgres-lakekeeper - name: Cleanup if: always() run: make docker-down-iceberg diff --git a/docker/Makefile b/docker/Makefile index 8d2f99a..e3d4e1c 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -122,16 +122,16 @@ logs-unity: # Iceberg REST Catalog (Lakekeeper) up-iceberg: - docker compose -f lakekeeper/docker-compose.yml up -d + docker compose -f iceberg/docker-compose.yml up -d down-iceberg: - docker compose -f lakekeeper/docker-compose.yml down + docker compose -f iceberg/docker-compose.yml down down-iceberg-clean: - docker compose -f lakekeeper/docker-compose.yml down -v + docker compose -f iceberg/docker-compose.yml down -v logs-iceberg: - docker compose -f lakekeeper/docker-compose.yml logs -f + docker compose -f iceberg/docker-compose.yml logs -f # ============================================================================ # Test utilities diff --git a/docker/lakekeeper/docker-compose.yml b/docker/iceberg/docker-compose.yml similarity index 100% rename from docker/lakekeeper/docker-compose.yml rename to docker/iceberg/docker-compose.yml diff --git a/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java b/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java index 329756e..ad7eb7c 100644 --- a/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java +++ b/java/lance-namespace-iceberg/src/test/java/org/lance/namespace/iceberg/TestIcebergNamespaceIntegration.java @@ -57,7 +57,7 @@ * start the catalog with: * *

- *   cd docker/lakekeeper && docker-compose up -d
+ *   cd docker/iceberg && docker-compose up -d
  * 
* *

Tests are automatically skipped if the catalog is not available. diff --git a/python/tests/test_iceberg_integration.py b/python/tests/test_iceberg_integration.py index 659e327..b31c1e2 100644 --- a/python/tests/test_iceberg_integration.py +++ b/python/tests/test_iceberg_integration.py @@ -3,7 +3,7 @@ This test uses Lakekeeper as the Iceberg REST Catalog implementation. To run these tests, start the catalog with: - cd docker/lakekeeper && docker-compose up -d + cd docker/iceberg && docker-compose up -d Tests are automatically skipped if the catalog is not available. """ From 85937bacf3c08c3e1c0837fa90b24e2ff41c7dea Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 08:39:26 -0800 Subject: [PATCH 17/20] test(glue): remove non-basic operation tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove tests for namespaceExists, tableExists, and registerTable operations that were removed from the implementation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../namespace/glue/TestGlueNamespace.java | 173 ------------------ 1 file changed, 173 deletions(-) diff --git a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java index ca9f69d..0735518 100644 --- a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java +++ b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespace.java @@ -28,10 +28,6 @@ import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; import org.lance.namespace.model.ListTablesResponse; -import org.lance.namespace.model.NamespaceExistsRequest; -import org.lance.namespace.model.RegisterTableRequest; -import org.lance.namespace.model.RegisterTableResponse; -import org.lance.namespace.model.TableExistsRequest; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -61,13 +57,10 @@ import software.amazon.awssdk.services.glue.model.GetDatabasesResponse; import software.amazon.awssdk.services.glue.model.GetTableRequest; import software.amazon.awssdk.services.glue.model.GetTableResponse; -import software.amazon.awssdk.services.glue.model.GetTableVersionRequest; -import software.amazon.awssdk.services.glue.model.GetTableVersionResponse; import software.amazon.awssdk.services.glue.model.GetTablesRequest; import software.amazon.awssdk.services.glue.model.GetTablesResponse; import software.amazon.awssdk.services.glue.model.StorageDescriptor; import software.amazon.awssdk.services.glue.model.Table; -import software.amazon.awssdk.services.glue.model.TableVersion; import java.util.List; import java.util.Map; @@ -476,57 +469,6 @@ public void testDropNamespaceWithNestedParent() { assertThrows(LanceNamespaceException.class, () -> glueNamespace.dropNamespace(request)); } - @Test - public void testNamespaceExistsTrue() { - String namespaceName = "existing"; - NamespaceExistsRequest request = - new NamespaceExistsRequest().id(ImmutableList.of(namespaceName)); - - Database database = Database.builder().name(namespaceName).build(); - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenReturn(GetDatabaseResponse.builder().database(database).build()); - - // Should not throw any exception for existing namespace - glueNamespace.namespaceExists(request); - - verify(glue).getDatabase(any(GetDatabaseRequest.class)); - } - - @Test - public void testNamespaceExistsFalse() { - String namespaceName = "nonexistent"; - NamespaceExistsRequest request = - new NamespaceExistsRequest().id(ImmutableList.of(namespaceName)); - - when(glue.getDatabase(any(GetDatabaseRequest.class))) - .thenThrow(EntityNotFoundException.builder().message("Entity Not Found").build()); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.namespaceExists(request)); - verify(glue).getDatabase(any(GetDatabaseRequest.class)); - } - - @Test - public void testNamespaceExistsWithNullName() { - NamespaceExistsRequest request = new NamespaceExistsRequest(); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.namespaceExists(request)); - } - - @Test - public void testNamespaceExistsWithEmptyName() { - NamespaceExistsRequest request = new NamespaceExistsRequest().id(ImmutableList.of("")); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.namespaceExists(request)); - } - - @Test - public void testNamespaceExistsWithNestedParent() { - NamespaceExistsRequest request = - new NamespaceExistsRequest().id(ImmutableList.of("parent", "test")); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.namespaceExists(request)); - } - @Test public void testBasicListTables() { Map parameters = ImmutableMap.of(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE); @@ -660,67 +602,6 @@ public void testDescribeTableWithInvalidId() { () -> glueNamespace.describeTable(new DescribeTableRequest().id(ImmutableList.of("ns1")))); } - @Test - public void testBasicRegisterTable() { - RegisterTableRequest req = - new RegisterTableRequest() - .id(ImmutableList.of("ns1", "tbl")) - .location("s3://bucket/tbl") - .properties(ImmutableMap.of("key", "val")); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - RegisterTableResponse resp = glueNamespace.registerTable(req); - assertEquals("s3://bucket/tbl", resp.getLocation()); - assertEquals(ImmutableMap.of("key", "val"), resp.getProperties()); - } - - @Test - public void testRegisterTableAlreadyExists() { - RegisterTableRequest req = - new RegisterTableRequest().id(ImmutableList.of("ns1", "tbl")).location("s3://bucket/tbl"); - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenThrow(AlreadyExistsException.builder().message("Table Already Exists").build()); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.registerTable(req)); - } - - @Test - public void testRegisterTableWithOverwrite() { - // First create a table - RegisterTableRequest req = - new RegisterTableRequest().id(ImmutableList.of("ns", "tbl")).location("s3://bucket/tbl"); - - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenReturn( - software.amazon.awssdk.services.glue.model.CreateTableResponse.builder().build()); - - glueNamespace.registerTable(req); - - // Now overwrite - req.setMode("Overwrite"); - glueNamespace.registerTable(req); - } - - @Test - public void testRegisterTableNamespaceNotFound() { - RegisterTableRequest req = - new RegisterTableRequest().id(ImmutableList.of("ns1", "tbl")).location("s3://bucket/tbl"); - when(glue.createTable(any(software.amazon.awssdk.services.glue.model.CreateTableRequest.class))) - .thenThrow(EntityNotFoundException.builder().message("Database Not Found").build()); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.registerTable(req)); - } - - @Test - public void testRegisterTableMissingLocation() { - RegisterTableRequest req = - new RegisterTableRequest().id(ImmutableList.of("ns1", "tbl")).location(""); - assertThrows(LanceNamespaceException.class, () -> glueNamespace.registerTable(req)); - } - @Test public void testBasicDeregisterTable() { List id = ImmutableList.of("ns1", "tbl"); @@ -772,58 +653,4 @@ public void testDeregisterTableNotFound() { glueNamespace.deregisterTable( new DeregisterTableRequest().id(ImmutableList.of("ns1", "tbl")))); } - - @Test - public void testTableExistsNoVersion() { - ImmutableMap parameters = - ImmutableMap.of(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE); - - TableExistsRequest req = new TableExistsRequest().id(ImmutableList.of("ns1", "tbl")); - - when(glue.getTable(any(GetTableRequest.class))) - .thenReturn( - GetTableResponse.builder() - .table(Table.builder().name("tbl").parameters(parameters).build()) - .build()); - - glueNamespace.tableExists(req); - } - - @Test - public void testTableExistsWithVersion() { - TableExistsRequest req = - new TableExistsRequest().id(ImmutableList.of("ns1", "tbl")).version(42L); - - TableVersion tableVersion = - TableVersion.builder() - .table( - Table.builder() - .parameters(ImmutableMap.of(TABLE_TYPE_PROP, LANCE_TABLE_TYPE_VALUE)) - .build()) - .build(); - - when(glue.getTableVersion(any(GetTableVersionRequest.class))) - .thenReturn(GetTableVersionResponse.builder().tableVersion(tableVersion).build()); - - glueNamespace.tableExists(req); - } - - @Test - public void testTableExistsNotFound() { - TableExistsRequest req = new TableExistsRequest().id(ImmutableList.of("ns1", "tbl")); - when(glue.getTable(any(GetTableRequest.class))) - .thenThrow(EntityNotFoundException.builder().message("Entity Not Found").build()); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.tableExists(req)); - } - - @Test - public void testTableExistsInvalidId() { - TableExistsRequest req = new TableExistsRequest(); - - req.addIdItem("ns1"); - req.addIdItem(null); - - assertThrows(LanceNamespaceException.class, () -> glueNamespace.tableExists(req)); - } } From 9baf4795efcad5258a3c3098317bb8686bde6622 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 08:42:16 -0800 Subject: [PATCH 18/20] fix(unity): use LONG instead of BIGINT for column type name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unity Catalog expects 'LONG' for 64-bit integer types, not 'BIGINT'. This matches the Python implementation and fixes the integration test. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../main/java/org/lance/namespace/unity/UnityNamespace.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java index 227a5db..6dc5d1e 100644 --- a/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java +++ b/java/lance-namespace-unity/src/main/java/org/lance/namespace/unity/UnityNamespace.java @@ -336,8 +336,8 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request List columns = new ArrayList<>(); UnityModels.ColumnInfo idColumn = new UnityModels.ColumnInfo(); idColumn.setName("__placeholder_id"); - idColumn.setTypeText("BIGINT"); - idColumn.setTypeName("BIGINT"); + idColumn.setTypeText("LONG"); + idColumn.setTypeName("LONG"); idColumn.setTypeJson("{\"type\":\"long\"}"); idColumn.setPosition(0); idColumn.setNullable(true); @@ -490,7 +490,7 @@ private String convertArrowTypeToUnityType(ArrowType arrowType) { if (intType.getBitWidth() == 32) { return "INT"; } else if (intType.getBitWidth() == 64) { - return "BIGINT"; + return "LONG"; } } else if (arrowType instanceof ArrowType.FloatingPoint) { ArrowType.FloatingPoint fpType = (ArrowType.FloatingPoint) arrowType; From ee464ed4a3bf52ebcf416f390bad1b084870d6af Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 13:36:16 -0800 Subject: [PATCH 19/20] ci(glue): use pull_request_target to access AWS secrets from upstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed from pull_request to pull_request_target so that PRs from forks can access AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY secrets configured in the upstream repository. Also simplified the workflow by removing the credential check steps. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/java-integ-glue.yml | 21 ++++----------------- .github/workflows/python-integ-glue.yml | 22 ++++------------------ 2 files changed, 8 insertions(+), 35 deletions(-) diff --git a/.github/workflows/java-integ-glue.yml b/.github/workflows/java-integ-glue.yml index 20513d5..6eb26cf 100644 --- a/.github/workflows/java-integ-glue.yml +++ b/.github/workflows/java-integ-glue.yml @@ -19,7 +19,7 @@ on: paths: - java/lance-namespace-glue/** - .github/workflows/java-integ-glue.yml - pull_request: + pull_request_target: types: - opened - synchronize @@ -38,35 +38,22 @@ jobs: integration-test: runs-on: ubuntu-24.04 timeout-minutes: 30 - # Only run if AWS credentials are available - if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} steps: - - name: Check AWS credentials - id: check-creds - run: | - if [ -n "${{ secrets.AWS_ACCESS_KEY_ID }}" ] && [ -n "${{ secrets.AWS_SECRET_ACCESS_KEY }}" ]; then - echo "has_creds=true" >> $GITHUB_OUTPUT - else - echo "has_creds=false" >> $GITHUB_OUTPUT - echo "AWS credentials not configured - skipping integration tests" - fi - name: Checkout - if: steps.check-creds.outputs.has_creds == 'true' uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Set up JDK 17 - if: steps.check-creds.outputs.has_creds == 'true' uses: actions/setup-java@v4 with: java-version: "17" distribution: "temurin" cache: "maven" - name: Build - if: steps.check-creds.outputs.has_creds == 'true' run: make build-java - name: Run integration tests - if: steps.check-creds.outputs.has_creds == 'true' env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: ${{ secrets.AWS_REGION || 'us-east-1' }} + AWS_REGION: us-east-1 run: make java-integ-test-glue diff --git a/.github/workflows/python-integ-glue.yml b/.github/workflows/python-integ-glue.yml index 6d429d9..6de726b 100644 --- a/.github/workflows/python-integ-glue.yml +++ b/.github/workflows/python-integ-glue.yml @@ -21,7 +21,7 @@ on: - python/tests/test_glue.py - python/tests/test_glue_integration.py - .github/workflows/python-integ-glue.yml - pull_request: + pull_request_target: types: - opened - synchronize @@ -42,37 +42,23 @@ jobs: integration-test: runs-on: ubuntu-24.04 timeout-minutes: 30 - # Only run if AWS credentials are available - if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} steps: - - name: Check AWS credentials - id: check-creds - run: | - if [ -n "${{ secrets.AWS_ACCESS_KEY_ID }}" ] && [ -n "${{ secrets.AWS_SECRET_ACCESS_KEY }}" ]; then - echo "has_creds=true" >> $GITHUB_OUTPUT - else - echo "has_creds=false" >> $GITHUB_OUTPUT - echo "AWS credentials not configured - skipping integration tests" - fi - name: Checkout - if: steps.check-creds.outputs.has_creds == 'true' uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Set up Python - if: steps.check-creds.outputs.has_creds == 'true' uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install uv - if: steps.check-creds.outputs.has_creds == 'true' uses: astral-sh/setup-uv@v4 - name: Install dependencies - if: steps.check-creds.outputs.has_creds == 'true' working-directory: python run: make install-glue - name: Run integration tests - if: steps.check-creds.outputs.has_creds == 'true' env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: ${{ secrets.AWS_REGION || 'us-east-1' }} + AWS_REGION: us-east-1 run: make python-integ-test-glue From 6f21c600ca12ea08727e1971574fedcaa63b7b7f Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Wed, 31 Dec 2025 13:42:41 -0800 Subject: [PATCH 20/20] ci(glue): use AWS secrets and S3 for integration tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use AWS_REGION and AWS_S3_BUCKET_NAME secrets in workflows - Update Python and Java integration tests to use S3 paths instead of local temp directories for table locations - Tests now run against real S3 with AWS Glue 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/java-integ-glue.yml | 3 +- .github/workflows/python-integ-glue.yml | 3 +- .../glue/TestGlueNamespaceIntegration.java | 30 ++++++++++--------- python/tests/test_glue_integration.py | 23 +++++++------- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/.github/workflows/java-integ-glue.yml b/.github/workflows/java-integ-glue.yml index 6eb26cf..9d7364a 100644 --- a/.github/workflows/java-integ-glue.yml +++ b/.github/workflows/java-integ-glue.yml @@ -55,5 +55,6 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: us-east-1 + AWS_REGION: ${{ secrets.AWS_REGION }} + AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }} run: make java-integ-test-glue diff --git a/.github/workflows/python-integ-glue.yml b/.github/workflows/python-integ-glue.yml index 6de726b..c83f233 100644 --- a/.github/workflows/python-integ-glue.yml +++ b/.github/workflows/python-integ-glue.yml @@ -60,5 +60,6 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: us-east-1 + AWS_REGION: ${{ secrets.AWS_REGION }} + AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }} run: make python-integ-test-glue diff --git a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java index 3143b1f..e37d6bf 100644 --- a/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java +++ b/java/lance-namespace-glue/src/test/java/org/lance/namespace/glue/TestGlueNamespaceIntegration.java @@ -39,9 +39,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -60,6 +57,7 @@ * *

    *
  1. Configure AWS credentials (via environment variables, ~/.aws/credentials, or IAM role) + *
  2. Set AWS_S3_BUCKET_NAME environment variable *
  3. Run: make integ-test-glue *
* @@ -69,8 +67,9 @@ public class TestGlueNamespaceIntegration { private static final String AWS_REGION = System.getenv("AWS_REGION") != null ? System.getenv("AWS_REGION") : "us-east-1"; + private static final String AWS_S3_BUCKET_NAME = System.getenv("AWS_S3_BUCKET_NAME"); private static boolean awsCredentialsAvailable = false; - private static Path tempDir; + private static String s3Root; private GlueNamespace namespace; private BufferAllocator allocator; @@ -79,6 +78,13 @@ public class TestGlueNamespaceIntegration { @BeforeAll public static void checkAwsCredentialsAvailable() { + // Check if S3 bucket is configured + if (AWS_S3_BUCKET_NAME == null || AWS_S3_BUCKET_NAME.isEmpty()) { + System.out.println("AWS_S3_BUCKET_NAME not set - skipping integration tests"); + awsCredentialsAvailable = false; + return; + } + // Check if AWS credentials are available via environment variables String accessKeyId = System.getenv("AWS_ACCESS_KEY_ID"); String secretAccessKey = System.getenv("AWS_SECRET_ACCESS_KEY"); @@ -108,13 +114,9 @@ public static void checkAwsCredentialsAvailable() { } if (awsCredentialsAvailable) { - try { - tempDir = Files.createTempDirectory("lance_glue_test_"); - System.out.println("Created temp directory: " + tempDir); - } catch (IOException e) { - System.out.println("Failed to create temp directory: " + e.getMessage()); - awsCredentialsAvailable = false; - } + String uniqueId = UUID.randomUUID().toString().substring(0, 8); + s3Root = "s3://" + AWS_S3_BUCKET_NAME + "/lance_glue_test_" + uniqueId; + System.out.println("Using S3 root: " + s3Root); } } @@ -131,7 +133,7 @@ public void setUp() { Map config = new HashMap<>(); config.put("region", AWS_REGION); - config.put("root", tempDir.toString()); + config.put("root", s3Root); namespace.initialize(config, allocator); } @@ -243,7 +245,7 @@ public void testNamespaceOperations() { public void testTableOperations() { String dbName = createTestDatabase(""); String tableName = "test_table_" + UUID.randomUUID().toString().substring(0, 8); - String tableLocation = tempDir.resolve(dbName).resolve(tableName + ".lance").toString(); + String tableLocation = s3Root + "/" + dbName + "/" + tableName + ".lance"; // Create empty table CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); @@ -294,7 +296,7 @@ public void testMultipleTablesInNamespace() { String tableName = "table_" + i + "_" + UUID.randomUUID().toString().substring(0, 6); tableNames.add(tableName); - String tableLocation = tempDir.resolve(dbName).resolve(tableName + ".lance").toString(); + String tableLocation = s3Root + "/" + dbName + "/" + tableName + ".lance"; CreateEmptyTableRequest createRequest = new CreateEmptyTableRequest(); createRequest.setId(Arrays.asList(dbName, tableName)); createRequest.setLocation(tableLocation); diff --git a/python/tests/test_glue_integration.py b/python/tests/test_glue_integration.py index 5f3569f..a6a212a 100644 --- a/python/tests/test_glue_integration.py +++ b/python/tests/test_glue_integration.py @@ -3,23 +3,27 @@ To run these tests locally: 1. Configure AWS credentials (via environment variables, ~/.aws/credentials, or IAM role) - 2. Run: make integ-test-glue + 2. Set AWS_S3_BUCKET_NAME environment variable + 3. Run: make integ-test-glue Tests are automatically skipped if AWS credentials are not available. """ import os -import tempfile import uuid import unittest import pytest AWS_REGION = os.environ.get("AWS_REGION", "us-east-1") +AWS_S3_BUCKET_NAME = os.environ.get("AWS_S3_BUCKET_NAME") def check_aws_credentials_available(): - """Check if AWS credentials are available.""" + """Check if AWS credentials and S3 bucket are available.""" + if not AWS_S3_BUCKET_NAME: + return False + if os.environ.get("AWS_ACCESS_KEY_ID") and os.environ.get("AWS_SECRET_ACCESS_KEY"): return True @@ -46,13 +50,13 @@ def setUpClass(cls): """Set up class-level resources.""" from lance_namespace_impls.glue import GlueNamespace - cls.temp_dir = tempfile.mkdtemp(prefix="lance_glue_test_") cls.unique_id = uuid.uuid4().hex[:8] cls.test_database = f"lance_test_db_{cls.unique_id}" + cls.s3_root = f"s3://{AWS_S3_BUCKET_NAME}/lance_glue_test_{cls.unique_id}" properties = { "region": AWS_REGION, - "root": cls.temp_dir, + "root": cls.s3_root, } cls.namespace = GlueNamespace(**properties) @@ -66,11 +70,6 @@ def tearDownClass(cls): except Exception: pass - import shutil - - if hasattr(cls, "temp_dir") and os.path.exists(cls.temp_dir): - shutil.rmtree(cls.temp_dir, ignore_errors=True) - @classmethod def _cleanup_database(cls, database_name): """Helper to clean up a database and all its tables.""" @@ -173,7 +172,7 @@ def test_table_operations(self): db_name = self._create_test_database() table_name = f"test_table_{uuid.uuid4().hex[:8]}" - table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + table_location = f"{self.s3_root}/{db_name}/{table_name}.lance" # Create empty table (DeclareTable) create_request = CreateEmptyTableRequest() @@ -213,7 +212,7 @@ def test_multiple_tables_in_namespace(self): table_names = [f"table_{i}_{uuid.uuid4().hex[:6]}" for i in range(3)] for table_name in table_names: - table_location = os.path.join(self.temp_dir, db_name, f"{table_name}.lance") + table_location = f"{self.s3_root}/{db_name}/{table_name}.lance" create_request = CreateEmptyTableRequest() create_request.id = [db_name, table_name] create_request.location = table_location

OItElf2#w}$*Q%8w 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 iUJO{egwG%6!pboG9u@(-NpA1l;}7A properties = doDropNamespace(id, mode); + Map properties = doDropNamespace(id, mode, behavior); DropNamespaceResponse response = new DropNamespaceResponse(); response.setProperties(properties); @@ -302,7 +305,20 @@ public CreateEmptyTableResponse createEmptyTable(CreateEmptyTableRequest request return response; } - // Removed: dropTable(DropTableRequest) - using default implementation from interface + @Override + public DeregisterTableResponse deregisterTable(DeregisterTableRequest request) { + ObjectIdentifier tableId = ObjectIdentifier.of(request.getId()); + + ValidationUtil.checkArgument( + tableId.levels() == 2, "Expect 2-level table identifier but get %s", tableId); + + String location = doDropTable(tableId); + + DeregisterTableResponse response = new DeregisterTableResponse(); + response.setId(request.getId()); + response.setLocation(location); + return response; + } public void setConf(Configuration conf) { this.hadoopConf = conf; @@ -538,7 +554,7 @@ protected String doDropTable(ObjectIdentifier id) { } } - protected Map doDropNamespace(ObjectIdentifier id, String mode) { + protected Map doDropNamespace(ObjectIdentifier id, String mode, String behavior) { String db = id.levelAtListPos(0).toLowerCase(); try { @@ -552,14 +568,17 @@ protected Map doDropNamespace(ObjectIdentifier id, String mode) } } - // Check if database contains tables (RESTRICT mode only) - List tables = doListTables(db); - if (!tables.isEmpty()) { - throw new InvalidInputException( - String.format( - "Database %s is not empty. Contains %d tables: %s", db, tables.size(), tables), - HiveMetaStoreError.getType(), - db); + // Check if database contains tables (RESTRICT behavior only, not for Cascade) + boolean cascade = "Cascade".equalsIgnoreCase(behavior); + if (!cascade) { + List tables = doListTables(db); + if (!tables.isEmpty()) { + throw new InvalidInputException( + String.format( + "Database %s is not empty. Contains %d tables: %s", db, tables.size(), tables), + HiveMetaStoreError.getType(), + db); + } } // Collect database properties before dropping @@ -581,9 +600,10 @@ protected Map doDropNamespace(ObjectIdentifier id, String mode) } // Drop the database + final boolean cascadeDrop = cascade; clientPool.run( client -> { - client.dropDatabase(db, false, true, false); + client.dropDatabase(db, false, true, cascadeDrop); return null; }); diff --git a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java index 6f1347b..0d5926a 100644 --- a/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java +++ b/java/lance-namespace-hive2/src/test/java/org/lance/namespace/hive2/TestHive2NamespaceIntegration.java @@ -18,12 +18,12 @@ import org.lance.namespace.model.CreateEmptyTableResponse; import org.lance.namespace.model.CreateNamespaceRequest; import org.lance.namespace.model.CreateNamespaceResponse; +import org.lance.namespace.model.DeregisterTableRequest; import org.lance.namespace.model.DescribeNamespaceRequest; import org.lance.namespace.model.DescribeNamespaceResponse; import org.lance.namespace.model.DescribeTableRequest; import org.lance.namespace.model.DescribeTableResponse; import org.lance.namespace.model.DropNamespaceRequest; -import org.lance.namespace.model.DropTableRequest; import org.lance.namespace.model.ListNamespacesRequest; import org.lance.namespace.model.ListNamespacesResponse; import org.lance.namespace.model.ListTablesRequest; @@ -209,10 +209,10 @@ public void testTableOperations() { ListTablesResponse listResponse = namespace.listTables(listRequest); assertThat(listResponse.getTables()).contains(tableName); - // Drop table - DropTableRequest dropRequest = new DropTableRequest(); - dropRequest.setId(Arrays.asList(testDatabase, tableName)); - namespace.dropTable(dropRequest); + // Deregister table + DeregisterTableRequest deregisterRequest = new DeregisterTableRequest(); + deregisterRequest.setId(Arrays.asList(testDatabase, tableName)); + namespace.deregisterTable(deregisterRequest); // Verify table doesn't exist assertThatThrownBy(() -> namespace.describeTable(describeRequest)) diff --git a/java/lance-namespace-hive3/derby.log b/java/lance-namespace-hive3/derby.log new file mode 100644 index 0000000..9063ad7 --- /dev/null +++ b/java/lance-namespace-hive3/derby.log @@ -0,0 +1,13 @@ +---------------------------------------------------------------- +Tue Dec 30 21:25:14 PST 2025: +Booting Derby version The Apache Software Foundation - Apache Derby - 10.14.2.0 - (1828579): instance a816c00e-019b-72de-0fb6-00000746a618 +on database directory /Users/zhaoqinye/oss/lance-namespace-impls/java/lance-namespace-hive3/metastore_db with class loader jdk.internal.loader.ClassLoaders$AppClassLoader@5ffd2b27 +Loaded from file:/Users/zhaoqinye/.m2/repository/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar +java.vendor=Amazon.com Inc. +java.runtime.version=17.0.14+7-LTS +user.dir=/Users/zhaoqinye/oss/lance-namespace-impls/java/lance-namespace-hive3 +os.name=Mac OS X +os.arch=aarch64 +os.version=15.5 +derby.system.home=null +Database Class Loader started - derby.database.classpath='' diff --git a/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 0000000..a4bc145 --- /dev/null +++ b/java/lance-namespace-hive3/metastore_db/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,9 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY AND SUBDIRECTORIES CONSTITUTE A DERBY *** +# *** DATABASE, WHICH INCLUDES THE DATA (USER AND SYSTEM) AND THE *** +# *** FILES NECESSARY FOR DATABASE RECOVERY. *** +# *** EDITING, ADDING, OR DELETING ANY OF THESE FILES MAY CAUSE DATA *** +# *** CORRUPTION AND LEAVE THE DATABASE IN A NON-RECOVERABLE STATE. *** +# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/db.lck b/java/lance-namespace-hive3/metastore_db/db.lck new file mode 100644 index 0000000000000000000000000000000000000000..d3874c99cbea4a587c86842f86d85c6c39c1b078 GIT binary patch literal 38 pcmZQjNwhFDOExe_)ip4*Owu(sN&&LclFW1sK)~F@EYZx+0sySw2<`v? literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/dbex.lck b/java/lance-namespace-hive3/metastore_db/dbex.lck new file mode 100644 index 0000000000000000000000000000000000000000..720d64f4baafc33efdf971f02084aca5f25b34a5 GIT binary patch literal 4 LcmZQzU|<9Q00jU7 literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt b/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt new file mode 100644 index 0000000..56df292 --- /dev/null +++ b/java/lance-namespace-hive3/metastore_db/log/README_DO_NOT_TOUCH_FILES.txt @@ -0,0 +1,8 @@ + +# ************************************************************************* +# *** DO NOT TOUCH FILES IN THIS DIRECTORY! *** +# *** FILES IN THIS DIRECTORY ARE USED BY THE DERBY DATABASE RECOVERY *** +# *** SYSTEM. EDITING, ADDING, OR DELETING FILES IN THIS DIRECTORY *** +# *** WILL CAUSE THE DERBY RECOVERY SYSTEM TO FAIL, LEADING TO *** +# *** NON-RECOVERABLE CORRUPT DATABASES. *** +# ************************************************************************* \ No newline at end of file diff --git a/java/lance-namespace-hive3/metastore_db/log/log.ctrl b/java/lance-namespace-hive3/metastore_db/log/log.ctrl new file mode 100644 index 0000000000000000000000000000000000000000..c23d2871bf135b162dee70f3081b449e95be1c11 GIT binary patch literal 48 hcmZQzU}#`qVBiE|7~ldj_!y+0J%$Ou=vNL~)B#Co1d9Lw literal 0 HcmV?d00001 diff --git a/java/lance-namespace-hive3/metastore_db/log/log1.dat b/java/lance-namespace-hive3/metastore_db/log/log1.dat new file mode 100644 index 0000000000000000000000000000000000000000..81a129c1d074d1e8f1c665393e5962cb8436da0a GIT binary patch literal 1048576 zcmeF431C%6z5i#j+}tFWa0!$GEpTZmS$ctN5U>jgA<(p0XcAhWwrPOdHX0I|r9xc_ zYSp?Hcg1RH_3uLUiPctGm%8xYb3yH^)u)xGwe{8YQMEqxRqg-xn>pv?%sFSWnc(yJ zy>N5xIcJvNd}jO2@64GILhKhp>|hRk z`T9lTK)n=iq2C{-vyl(q@1ZZd=_WTqx%my9CH2M4^mB;5^r0*IlOX5u=K>%1=4i)- zf62bjxzCZhDfqrW1xwh$Pv7<2-HwA%Gw{2uIQD2ejPdTOZNdoIx0?_b#57&M(MH_g`~S^>(BnnlrFo$ zknZx+C*5a4(%o|9mA?!~_qZY5wWf6BcDm|c&i0UW|8(nre%_QW=N3b{8%^n^F=uoB z5R&fJrmSVAbh!%+=?2lv5lJ4#G&wM{1-Ghd7x0}*UW6s8ELekxE)?M5d`s!?K zn<3p{Q@Ux)+1S5@r29zxr?mm;es4&3^t4Hrw@!oX!7fNV+TDz5L^*bOkf~(n;!M>Hq2IXA52xl5XYVn^+z5mAir?hIF$| zn{mbcIcZbW2X3bYBcf_mk}>o(V|zlp!6pH~yR@x6{?4B(4ofcV+7f z-)2gexYdxZ-jr?{Ta?6KLel-)A6fz}%8YXj={B3vO(VM*?+HoQoa}wTWH;jrhIHMg zbkoSL=y@UOzEH9zpraIZ8Pc6T{jTWWL(+ZtKrCajEBdn`-F}nZH0JEgn?lmPx$o7# zH>I0-$dK-!Dcv;YY;sOWx@$Hq=r^THt~I1PeEOvOL`b^2d%sy7knX#NbVpB{bh9>x zqFW07z1U<|Jll}&VN<$kEO*7P4@sAG(=oPK z__ToHqlR=pGNqeFcC*Vv(l!6G<{neJ*=>e&zc!_tMs~CRH6+~wZ~aLsAlkR2;nbJ)oyEAe^(*5P!OGroZm%B5{4C$7fKI!fXN%z|A z6-xus{fi+T$$px0c5Yorx}&%3`->^v+>9Yzy(!%^=Iq@62ub&&g@!oL%tdkaY9!_;Mg;7u;`1cl5MLcUDD6x*h*9?^%=GSz8S0zHs`a`$kB*8^7~k zc>(EuYe@GkQ@Uv^cW3v8r2GE%f1P1UclJR;y2nlFrm@^DEC@+=Ny+y=XiB$mr6JwZ zrgYQDZsCVQ(mip_;Kc#yPWYwErkj$!o9R15U-~5VL5L}S*1Bk8NV?mf{0;R6ehq5T z3k~UJnbJ*T&MtZ~EZu>(Z!x7?oNq|CJI&wQ*9t0_kY|| zep5PfJ6+}O+|?oJ{_@@5Ga8?z;@qnY=?Gl_Cf#|-kaQKl{P%zsaNa6Ix`#~ZC?(TX?#}yINV?~;j|RrG z=RIOb_pmA5G?u$%%^~UTuYUBTnX}7oG^Bg{^hx*gkaWL(_lf6B=}KlA(*63hNmufk zkaPu&ZwzPwB_H)mmqViaTjOagccsfh(*5bqOTK2ZE4|E+Zk8$CG?u&4FNdW2_BmG_ z2uSxcL%JoWO}erjA?Z4=`r0c^>B?ShNLOJ>H;p-4E<)1vzwG7Ln9`M>XGm9XN;i!; zTmIgVbYDGt@=3U<#YYgEuqN7iSzD!GaXpJ zqn3>YS$+XY$8(2c;=0JW!^{2p{}Ai0VqN|nzoY|)GKan#3hVzohx$mw+~HM@n-7qi z{mM2k;Q>5-jox| z%}ULD+02)8G&VOjbfy~WJ33RP?VasSEv5Q*XJx9sBh_$8eS2wT)ta)hGCsYczJ25h zU+CPnxv{IYzNImp>a5}m8|pjjyZ9TJ4#t~xZ=hCFsODwx`9 zWd+~gLcTV&Hg4#u@1&eqzonBytyCF738Cu@v#X<_UPV`_fY)#7Z0l-jZD?<7X>9Fu z;~UAz((z?va~p-KGS10Pw-l%>GE&^q)Y{atrNx!Qb+{^&!j}52VTa6%UAp`_E^qGg z6&f9y#ZhBtQwzb}vYxRh+N~sqg3?~Up=oPsV|!ams+5Xp^OnYrRB6fjrcD%2NqYIJ zbmiK#88#QYvTulfBn699Il@(>_(vs%3)=h3DNo{OvPpxn2 zR8@jRs7Y5>)mBubOSYDjl%(lf5*fJ{QAJt>uH(^v%>+=&8aFkD(%@Zoik^?9a$c4u zFiu5Im6ip?tR^v6*H-z(Ea}bkT|aa~N!pXGYC2`(jENAeDqXdz=5HvLKW`~JE8XlI zD>qdxR!%ptl60l!Ge!~f)iC|Df`ir-Z3A^G)C!lRskoko=$txLlCGin$DO*U6#J@>zh(#85x2c9 zNw1=RQQ?gD+W6wz*xXi6&E)Fzs;Y6vHj;M{x#mxsDXP~zSuR&`J4$^o-D9kDLjm!mUnMtt<#pat-q9p0Mv3+xi;NNEd>q9=t~YN>2@XEuUu1>y7H37_Qn*C zwl2IlRpK^-DH;QCl1kT^qa$)tQI-;kyq_f&i8JOGExoy0(3m_X+AtoKPB$tCTJjk|#XSoR66w5;2*Yd6#%xma!m#&y(amrYADconm>5 zTuVou4w2K>y*oq4BJ(*h-x=DsCnKH~MPjzdb2@JFRKP)VzUrBFQsnRK?;YOVx4C~% zuB6MwbaQ6UVEyn=e^1}efz0kq-;lb&zGe;Y+0{MNy`wj?eqY1zz+nG?z7-)*(s}Id zJ<*=LNVBF$q#4GO_{qzYoGN*Y=>vv5b4A>JLPmL#OJBN8WkwxCc{X#(1oBUO_$ve| znj(Q_1}1G7BFz_hjt0tj_``_yt78b!j46_+$efL02$U3gPNz&Vs1FOIzafG6Wu+;p zXTfERU;D;lhNncmv;WcY`puuK5 zw)f`Imu$XjrxGu6I_E`$is(CPgdDK((MtZz2or3a?41q$y_KsB)oen8vZ=Bxx}wxf zUX-a)5?xWMCojrW853Pmsti#kWdE5ez0eh z;`(T@ButgY`$$!bHASt5sL3b{?>C_}2LG7map zn62#i#h5Cipd*Ia!bXT;QSGP76zGUCR_i)Sm6<9{$dSZsTqjger^*cINMg3FfvjO5 z^XVI5HlCac1igS*PT+yH+wF{1a=AsZH1^Y@7mz~869`IF;Sha4@P_ny*#w@8z*^`V7f_F=DG4YF>z*pX zYyz{1_2pfdO~N(VVFI&>df(ikf!QVjOCx5R1Xm_-dq8u3R9IsgWnRTpKTa`cRNTJ8 z8`5h-1y5lx4Hc;fL&fbG^2UaWZ`lnMx8LRj{Vm5(u|yjxk`_b7?Z-U#?u?2hVo8*t z;&$Huk7rbT%VMZFNc(>qhKeO2Lxov+CzKRJrGL<;N|Rj33XfBwI%7Oe!Q+%hemjO=JX9Y`b9=fUr|1_ZLy!NU7eFr< zy`cVI)(cES#htwVrJj4B4HZ0v!8BAXi7-?gE+TJisCd|Js5o5Z1pTmMs5nO(DpJfo zVvUN!wEwRX?*K*8gmxSmbd!8G0W_SpBM> z@_W!{ILT*6|K`MZMChe6&k0#G@S-yz=mmal$$89= z1yHDEa`kG5$=}feD6p-NMxs8fnqUEx)=u8ujZlnb1e{viifPR_`T=i9udNw8&%v~2 zoD*TqILhl^ur=cmyEWqz!U_5j$C`1jwq{gt8HliEe4@g0?@qfoSDYJV&G^K2a>>?= zM*`LicaM)xyx0lKHB_7%GF0@MT}(iMW)ZOt%p^80!IYG!K^LZ^L{Y(%6rvIseEs82 zNr8IAoeqDX9))K?G8fA;(y3LCpcjNE-Mh95OjY%d%3UhvWb+94@y}-Alg4_5< znC+n#1QaDqN%_A%CB-yUe6iIV(rZHn&vP&h73W46D!$0;U$CL#+jc|67eDL-{cXok zu~Zu>>bO2e7%IN_JP_CZwrhwn>Cif(1~*1{}=T_3I^=Z4yvhG20{n1hY+)z0YFX z!sC=E0|Cq?QB?3aCEOdsY!Ya0VK(urCsVU-tZAtDx8Hk1dTprSDGa8eVrhh-;t^i| zf(;elu^TELX?KGDj$^1ePa7&WTMQMCyxeo|8Y<2c=S3MR9=V5HvZ3NT7DL4&C!C;M zL&bR^LxmL1oUE}1pDeAVzk_-dsIO3updQh7loPU5Ks|zbgr`cr1)u|y`*?l@W}9#? z%pc4)!Q&J>PT`7RpZGGCM$2``qS0ajl&H=ak5lkCWnAw*;BkuIUh&sHPBFFydE!oQ zNUseQJcYqDRGb%KsCa_czhFbfckPCXC!TeJ{;p%FSf&jX*HSwfHKXFm^F8;jp< z7G*IT(Y6!dlo~*?-n~j zxrU08kf9>DiHp2FAF{cEj9fr?@dKqJJ+RicE%fO;e)PPcjly z)Dz4?RXVk$xZrUL(Fv)vc$^YN1&>q0CFSq>af(`UlB@=t**U-QhVD$lMku=Ab^}d*l8$|_^ zaU;}MtZfoj)G!&>Kh5KGKThFg;v)(w9;bv0DjuiUOk2~R}OEy$I7BEyedzi|(H~RK49sCGK`0$w<4$$EYC;610bKma7=UOw$ zLe`A2pDke5p}<@abEFzE7vz7*loaStu&uzhVt=V!il-3nfQZOYYugO&2Mky};z*AE6NF&lz`VTxMWfUrZhf`8a zYsRu3Z%D7L89dLyv}Tk=STmOK`WI}?_<`M;vFyuE&_8gj8RgoVaVP1)QPzxQ&v@=# zYeu;!kFsWzEFza|&GXF&=a_zSagYoFeMh1_bq6`G5+iWt5A^`O$DuezG)g$Ny+(1h)Yr^&l=mpRVMw!WM zz9t!-kO{qD6043tFNo@Ppch0@Io(rIM$wkWr5BinirQjtNUseQJkP;2RFp>;Dr$NC z3pP}ov>PgFcRN9!bPN^eYeU7yxk-wcc2RqW=iW6`oG;FgGE~(53%O)N#Yu~yqV}gw zP_Cik{E(rdH?w}<_>_{hl|(|)w_z4z1)eGe>I+Z! zo7pp1KRndm)3$L!&A$MHR_ohS0NnPw&dX8+$pZox?+!mAXBy-#OHCQ}<9$e_x)+ zmLhgxPhZc_#ZqLKmR*q$xgu6TWhal?R#E~-FN-U zwjD3X>>Q%RpFavDH}FQvtM>jEQJ80mh56JwFVe#D^dVWHp#dsR z7g#b<2dv$AAzWaC6YV-7szi06s1!9)tQ?p88#04C2YU8U5zZ5jhY%S9V5|Pz?JTK;(|i4R$M4Wf|z-(q_}#F09%K5@5qb*9s^I% zbwXS$)-j$sT?|`?dwV&1 zlem%N+9bvD=*-Lv4D=7I>=^3q+tod=t8wqn%pTpKH&HzrX?c7%E|a3bI~|ORv!tkv z4tp>&a8u7ts#?AM-P9GW+?46d3{ZQ&YyG~V4EG6nqK%3WWqM0y=!X7XQd|~MLu`fK z8oCaQs_*5Zy-;ix9kF#!v+B=Qy@BMr z{R=i!{LpTwxMZ#q^bZ|FMOqsw9^#}$7%DE==(%?d6=~|!c}oudETHc!`cm1tWDmJy zL&Xm*hKfrLIzhRHigd_O5ybcMxVR-&m*ki@j;u^gLcChDdkyt<{!$+ouZ@dW$Li*c zI9`dqc0 zv$JQA%4~XYXLoNVF5Vj#?_zOk6XLM;a~Jv9(Adz_Qr{dG?~jYavAWbq*lQA$BT9q( z2)T3Sk;TP5aq;0;-8m!f)+WSJ?d}u2b}|LltTeJu#>LTC-BQT>ObTXYZ84 z_)A>;QN^_;K_ffPM43fc+SXs%*w7i5IdLgtb=AI**Cu4Xc2__$t#58yAD4;jTb_IF zxsj&V(KDpD#@6)d#x$gljNbN!oG0W=nWV;7&Wg+YSY6GCm{k=CIaiB$CW+ag#GD_O zb7OU@e6A`Ja*=kmm>_IzX^zV!ak(f~x7z2Z%F)%87Q1nvf43TnkTPo>i|EvOTA5Fs zO~?{iN<#)&Mq{*Sr6^KY&y(j*A zV~(w|gB#td>V({)+n+1cISs@|FCf98WkPP1+qi&iSN>NeCE?u0i?AbL$8g-1?I5vC9Zn>jSUMoq#m8rO-N*M3%8|>*E=-DmBYsVOb z2Sv8zLS(Zy#&|XubV6P)Zzz;$*`sKzPRJK(8oeWZ6D52n4dN5BPmQu=zj9iekT+_l zG+>~Nq26#vpAV~Z>h)fv&q*Q9&Qw$Pa8 zmFm1EAz!7>U#-q5<8IS6{k7_xM1Q?Le}g(F`QD`6ld?zglYDR1=WkKxB;VWg`P=!t zhU9yv_D`A|os)cr^!a<@a*Gr*s4jQx9O&=u)r~4yWU0-4pS+XXwZo(cc=wz71~Zh` zWXSc83=d9WZ8wL*RN^LCv+kDf=bH5aDaxWtzP}}6V$8B$4c$l|f9I?^CY9ce_Qj-=hIBPs6cNGiEHlA5iKq(-YF zsmba{O0YVTTC0wvxT+&5rs_y~r#g~0sg9&Asw3%sd}NJI9Z6$TM^cH@k(3^Fq~1jx zsS#2~YE0CT8WDA*>Z6WSH`I~pggR1PP)Di*>PTf@9jVN#Bb9Y^q%y9KRJPTT%CtIC zSyo3X!|F(7R~@O$sw0(EI-X4mJ3S)xq1@5GX`Eq9W6Ikr3TZ1>J3W@yR$T=z~Oo@9a5Poecr!jm8v&kWB` zFrFgootepkDB(Z7Qjf>;~B6%RE_!ZHqIFOtCi+jf;c_21R*lt-#9)g zAT%qJL)NNz$XXQ-S#^{{$wDvx{ha`%)WU@C*mRUb$s&7N$EBp)O^ol(DgHn-mAi8- znSQsG@!fXDcUu|XZDoA7mGRwH#&=s8-)&`lx0UhTcE)!n$Hn*vF+P%0{LyH}M{@Jr z8)j)e5{uR{DKIO@BUX?{tRRnAK_0PI;3G+!LVd&v@<`IAP#+l|$9sw6y*b67a&eh8 z_}<*Od&A^-Z_IYXit%16#(S+8@3msQ*NX98E5>`R81J=Wymx#UA0&(q<`jR{rDbA# zFgIzb^AE<7HLf3%@Pkz6KkwcO1ZQRZpq251R>lun89!)c{GheYKbV{u*@c)2`EkN^ zJg4|yqSJRgH)*N9$79JeT|XwS<5nietxS$vnH;w=Ic{Zg+{)zmxR{(ECMR-=zv-sW z%<~huNlT48VJ$)@tV~W=nVhgPIbmgT!ph`?mC1>5F?p1jJepJd-DoC{<|Y&F9kVn% zY9F{gYSsH5wd#G3+V#Fit&AVF>V1z|^}a`~df%f~#*bPUn>Fqvkvy4G{6m+QS-MW< zCX?}ik?cgb^cJS2rw1ZOw|5Q%#ucL9D%1u7sy<@^Z z6|*(^r}Bz_>-sU_pR&R~Wrcsr3jdT9{wXW`Q&#w=tng1+;h(a?KQ%u1&l3D+bBa9^ zpNZ?)+~n0RNE80EvE)L_oxI}b+&h8Ltni<;!hhBZ|5+>iXRYv`wZeba3jbLv{AX#L zmhUDtfM;CvWp?=|Wp>VN=_!Q1vC|#P6Arp#F)q^`i*cFm zjKjDr3n_(#l)@QqGRzbfQVPHA-ZBu%!q{wCWVvP4IAo!fOQDrZq3ziNg%+K9Lwk_( zD2?+djSF09%{0!VG(PIyGSfKEp2m4LO-#m4%6?u z&C@%|lbb#(KeYW*@}4X86Wtt9C=#SC8c%d{4~uj7iEi%O$UB$&>HU@$w;mIn^iV%J zcaGRnbWA)yUvQ*d$ur|~#MMRF$HWeOrM$d&kK=Tn=QMc+J31zY=v5=-Yko2|M+}?Z zUgmgP;Ca(-&r0TvxJ}OC-(E-*+bbP!X9v73Op;``I#DEN^KZYm*E`-81-vaz=Fbst zaJ?1tZ@;&DV~+TsE5Ju*6Tv)#6dZW_tJ;U3N9B}l^TCQZSTQ2-hjD$ob;2Fo;nt->p$usAO-?;)%{rcUAx31*#l2jdk zZwN43(u{IdsV@iwbzyS;h+|61??*x^FP|-Aj<<^f-Y!lqm?QI?IP&J|# z6La0EOJ~viCf(8T6sAi>vzp~}rJBej#AP&8TC7a3x{LSEQBu~&@MUe-4qw+9BxzDw zRD?G=5vu7tmLM`orBPGR{aL~%NhYau=7{SvsoJx05^(Q|@}fvlwmG7-P}=udqTFYR za$hn!%6)E>w~QI(0ZWtzEKwe?M0voC^3{=1`hnkO0e+iBl-n$#+-4EwHdmB4MT+7F ze$W!-K}(beEm0nHqkLCnlBD~j)@K|Jo{Z5|jq&#^rI>HB|BYe(jlNP~Gx`O{CQt&cI@P#D!Qx;L4a)bEQm_eMf1aZm@;*Vnn@vJ3?XPqEuK6g|X zexH+&kFbGHJ>3rWyfQm7V`O$@#*nqm4TX#gBmF&HkJJO`dZZpe*CRV+neC=0KQcY{ zJL#c`C9*JD@WN=p3-y!|vQ88mf*0zilM&aW6I5tPP@yG3g>Hi8MkeSsCqXY|+nq(k zc@`1pS(wkWh&az8;yhQxMUf)<%TUVAeM5VbspzaoMQ26IQif8N^rS55NmTfPnJI<(^Rm#j>(E_u`TDAT%9G}B?^zp=SlHFvE7@-C;OW6A?mv$(6}jQKLI~r7qqyCZ5Ry;}ShMzU{-_;8+j&c`|@Grb^p8+nZWS_3zHgRDDN^S7s=!tXfl6 zR>r5!LIU~a5}mys$|ZU!@Dxd|`7tExpju)Yh5~MN-;X!!C3j z6~QRz0^eTGPUZ|<=8tPSal?r(Mmd>`Wrq+h`#+Js` zPB*@hoGcw*MmD!ms4C-}>~u?k$|57hElsUWEn8Y#Ib4UULMd#i-x_wvyx1izo}u`4 zT;AN}D>OPZi=#$f{GqF3%X-G5XwzCC8cKWphNi8ljqPnMsZuJY&088fQl%w&*|d`M z@>S`|wP`bKE_P+(zLu&?Z>(?bXiQf*M}5}WzNIl;LH{Z%%F?AJ{#8$mWo2msV_6l4#H=PU zSJzhg#VpawtEZAn@)wQq0TM|bv-(wUpUk%egD>!If(VX>sO43wZ zPeXK0ohnJ!Q2gUgT~vyFRmfkn1MP_0-j<|S(Z8s0#(Qmi@u@|MO46&-tE$Ew+eqF; z4rbjTR zIj2T|s-JGY|3>YAvw{>!vYJ|?sI-swnlJPI%8t;C(amWtXKKx=^jdCJ()wgvU2{bD zH=+Zm^{vuttEiNesNYi)q*?;2B)zseUA0yRtglQy^tDb~s+Y^6mYYT%fgE#L1upAC zY+|)vI~^IxOL?gj)TFB_YieuORIje79ky3A4jEH^D0S3nL6RQEEM zOJ4FzC1;gCIaH+`#nCUYqhDA=ifZe;#7vRAq)*c7V@lqjlICW18=bCiq+H@zi6f`8GFFB~B z+m&>`a!pz4%1avC8&f>my71yuiQ5dOXuVHPQt3K#bVP0{%0wdXXNg7PjQK@NZ|)X3 z7?NvK0EXm_w3SYnCZx;fpw13!!Avulz15L5lLR(r=WiH@Mz>wTCTq!$> zYif(MuP`tS$xB@}_DVc5ikzSYz$v#Fk}GSf20Q{2L-Nsj4vUhhdlA#XtFM_Jye89f zS(z{}Bxhr@t+RfN+xH4`tF7?NxCNB1>8qanXD#7RO3wn=PZzh+ zmu3Nc#NGcv&DkW_@rE{=3C4s7BRIfEIIJ+gmL6%N2Vu(GP%*Y z>t8+mn=N>&|-#FYy8`|~vaZbsN?q4ZV;`#DR z1TnXJaA!{s<5C~aT3UCSUW{?~#GnfWe2eeo@E`su8_3Npy@Q9kq^@d5Du@*2V=+Zv zwW_kJx}vI*jy0=mD#%4WIpy+1fqXRSwGr)MB9mSzy5bybl~|cIfqcvsDsT??Iw$Zajlhpmny#+fQ*$}u{1?ql1X^8Hk>d^=NzKK5dNoja3!iVxraKcAt4ug-n!P6~zV z+|MH_!4SD6cpv++lfIvOl^{D#m5<=jddP8I32Ls(tXWgBW7X)DV3wHaR)UuL&W1~9 z>V|KE)EH={tQx#QRfD|U-9xlh;BW%YG`w96Sf@)SaU#BY3Vm*VJ9&q>Jj#C4X(* zp?=qi)mL|pzMW#_{_5wJx^wh?U)||@mgE&T*X`#<(N}kl{(wT^x^pUAcf`lYE#dow zaME{5)t$|B&Fw(QW1h~n>NPv7D=MmJLf~kcM3(rmud-C~^g-)vLh3VUq5id629emQ z_JmpAGt|<(M`YdeE0H@qAhNDnf6s5v{6j3>`6DWed-t&8HS~uicbd&le9n-*TT8DS z>nf3_vwnQiQ~BaHnFDqLzxOO7@Eaoo*Nx^_iS-5UaKCr25jb;q+brT9pFH=fs_Ec< zEn)F-|Kw^zdge~j>&jjw;uGY~RnEu#lW#EsXYS#^HTSU+OWfVSZ>C77ynpg(BXH*K zY0h0DfAZWbSt%N&yl2stWK>C=q>?0`V*PKws-2{JNM=ZqbSWLaO5{(FAuGy0hM)Sb z5jZpCz*TGP1@4sHF$5=uZr~2X`)Z89nPDz9JxUYn5(SfI$Sur-7~U7I|0GG5lB7x$ zOpqZrpFW27hwFbhaHkxOAviH~19uqSAFltgLK@$+gP-BCyNzTr!*JjZ!!ZOWhHl`_AoBt4|5-

^h9#81JTJG+QA<^1(()3EAH#6ORLRlU(k#P2((##sxPL0{;6 zL8n~=R^2J|?7(U3X%}yQ=5U5dApHUTTn!?DqA)^hqjsvFhTi%6i|1_0jc}ix7*01z zsL`p6hsh4d50JJAvNvUH9-qkX)0%yf8x?+FiiVEyO|JsV0T)>7O{-gXm15t3oCjM)>IK# zMJZ$amaW*ZTs*xnA?0>U#sFsml54rRv5osoHvcyPH&DKBU8%^)3d?~A0Q6Xu^(f$_ zwLNzb1LI3_=fo;sJG3k__iLW<=Vp0Y#!ZSfl83Iu@UonszGJ1l9}=spUhSSa20Rnx zE67s+S+{Zf1)8Op*o~Db=`&gl4Bpxl&4mN#9mw$C_nh*3W9@CntIhh*l3klNfe`S0 zumQ|*dG0nU#}*9@ua4jQ%4nQ*X#H&VFmUxW*3Ni_w!+|m7xU!mR_RCKrOhh%7e3l&mTrEi8Nf#vNz`!aY{r^HEI?f8vqQ)}1d0e&s!)j? zbhc`zv^-R3df zEV?l?ZG}c}QM?UdkH2gBLF1WTU?0XOWW+~cSnz%=F8B6@qTs9lCnze!X2dkM=ZU{8 zYVe6g9}Cfg%FSrtw#oI@v3Df`tVe%lI(Ci7GqysyNv!aBf89z{jxpiz5LRr|2N&aT z0tO`aO)h}mDV^Sra1&YLx`u0<(0}Awz)S#TNB^SzENOwBcVTm zK_3t+Nf6_%j1TTGs1LTmZ1Fvq!O*hnl0g6R82al4?kKCo;yQ29!xL3QPc_LKMUR*` zeR=QXhllGc^$L-t4E}?jk3#L%2zick@62=H*FVjz0FnB*$?s5?(f^3^lKi{1QOw@m z%Gtr*?mIT+zZOTe2?JCOv`+?NQ>eXQB_#rDRc&JFpl6JxE|3CZLx}m3wK?L9kc6>6 zTp4-yM!9F7$Q!Qnq44OoFN+<{v%O`s>n;}JxW33r*`naYmdN#;E zNP|@iG4^oaE?7^-URJSx+Oy=uJCGk)P+CZs{xqh^Fyy*@_U8~f#IZcVqN zceUn>agv=fVy=w3r(zW*E<#9$Sqq219zd7^FO#6J4ModDNAqZm%>+U+&&d z(Fs}7eJ_o~Nz-9pcHsQ(CpNoB%|i{_A#JaHYt3z8lUkSoF-^(ON;@5AexyP=pFB;# z=sYxg|J-Dp@F`hsYUypwyG*>0gDtfwKME&tbsl0q&*E>8v7@PQg)mNnkXMZjZ;6;6 zL!3S@7aYI3HQz}+mJ#Z09ed`!F&~` z@M~qy$(KZ%pFzI+jLurMMN!F3*&cIwX~&K5ia7KpQ+@M7n#0YkY~2O~nHcKthZyoC zfrpmp${y4#MqDS&kNY-6tdRWd%R=1alSwG3@5D+m69*cc#z+jc>b#SR0H-kfRb>}# zVU;`NjX%_U;SpL9j`*47J|VQjV6u*Mn}{muXCRs7k-u?)Il)7^;ni`As@5j78A%9Nhl%UWHkM$Sm@*~m+)m}jmZkBxqXI{+@YiSR}GT)E{4yOs> z_Yf{4vsfgeO54()->GeVnMqtwn#&`2;!i`)}X zD+-pbYB1EG8ti;k*-8FM2~_Mw$Pp(DAmS?Vpe`7gr8dgg5#sl_%;SeMfu?1X?mC1E zpGODGN?VK5+B9_?snfX)GRclyDBf<;*@%fa(Qr&E?xkmFynHUfv8z$jmp$ScJiqJw zps%(-)7i5yXp2IcpjWbcchPj`bqwM$dWKtMlFU80cH|`#46tle00`LKl#f!ggW5r) z&FKRH(gtA--vYX8nijh+w&g@x4Uo42KD>FKAKlrrexlA!lJekFj{EP>@GLprbMp|+ z|Jt#6b#T7YmJ$py>G|Zo9V#{|Cw@iSn4Y~}dFa*p!hOZ$rx%=u5Ez4MBcLmg6GaqL zaH}T8x$q8}pM4yrj1XH7R+#xZv+=k4HZ&CR%R`Zk-hr73oV>;rB)s)uVC~8x zrW9orHL)E<)wCC^6Q6J-3AmC26cY5rMj$Rtmv6>s4s(CBWBYQTwXH3_ph6VtftJ%8 zzAeR{z2R#EF*@3U%B;dCOK!ziv2(pAj^Yqh?cMeISsDs{y#;wF0By|)x&dTVe;k{h z4+w@}`kw>kkGx3_AfJvVwMF>-?KAsJ4uru3jxPmbh$Bc6Y7kMoyJYi+kT{GHssw0p z@T?4|$Hi*i{~sG8*h`s~YH%PRE!h9GG5SX)*Z6j+dbM@fI2TX^Idbl=v zUcgHmb6g|mzJjqM6mss7$j)`~UMU6&ngHbf2J|Qp*ghP~m-AE*%4C@U zg76|9$=M&R4>JSGA(EgQJ=AH`xDAJ9V`;w4tur;&uBIc}CWKbIv3C zh7N%pu}qR{KCEkD(ij^)Plgn0QVX@DXU0#dFnRMit+g;QC1hk|4Rs|XG*Km^JUWs{ z*zKO3PwLa7$j)7casR1qkJKWop{wQMqx~-LY5t?XF4N9iS<|0q07CEp_~AV`46_DO zn_<@WcgdwmeEI5=i_1y#;SF2A0nlh+?_=Ymh(?NoB8erixzKvM{G`~e4inm7t)y`8 zys-ZB@pJ^Q=t3X8o=r_h14Bm*qQk98!!ha=mUO|N&xUbVLUpCR7MYO!jwixYXsd!) zP;aDq{fmp`!Hi3pTI0{4cTT|8D}^nzT$R) zAX;h#TX>OTQ_SzfUOS!A1w&l!T?0i(l(qy!Ej%CqJw1W_nz@X48|cR-b%rozb+lLy zZefn+@8t?0Mh|(jSFmrO`Tdr4yyvj+!$JIklK#>Cy8cw#uuo42bK2brhFoE%e;y?U zb^-*|u{kETwwA+D5XC<_LHPwBCOUnX4N4g!VIYhJUQK4M02aZWL4k^xx0+6;z?Nz9 zXsxt$6U&5=@Q?XgDfNZ@!Bm$&s%P^AQBJRfVP6OOHJNBq5Jf+FHv0@+iSX|5g-Y^g z3>Au^DBPaJB$Lu>8N=$9m%~e<^JlTsH!QXOa`MlK_=iab{S0{kFX&ESiqu~6n7uUA zFsu{&yN>y783*qG)eBCTx|<;zwb}d!9EFg_^2y)UYDuTucEgv;$m3Z+$|mVW6~r6u z@&xwE1L~V#IYzmV-ku*(Yg0FmSs;f)_Sqy)6*LYnPWs6oxRO^}2|FZu3un3*!|DNk z5T=n+#NfeqHk{LyC3MB{P^V~UKs0Drf|ggX4f5VeCX!dn7$gv~jy9M8dm`n(LKrEk zWOD&shQPoN83%%P^2M<-hJHjM(V2vck0~<*~yb)PcSG&8u}pqij+0K zj!AU&cb!nkLe1Nl6uuR1c@RDt+-r0_d1R)H2)}V&fhVL(ynO+W-<+uhmwW>sI-hHE zvqzFHs794LNapcT!WdYUVrdJrq%ry}1`;JF>2GllW563SbU4J!!$cd#!ay~mqN^gs z3;{1_8vO-dW-DV|FJlC(>+4Lp(l$|t2H`~oCk~W{-0#zTU#M5)tYS{@v}wYq`<-1E zN>m76-;ETdgGsgmrN3N(UkIR%OpzVrBg@*mfT3f_=SChtpdtc9!yG3G$<^=*{p zx+{ofqu)IhSO#ti8&F9a&654#3i89fo#l84e+nUe0~}xPTw+0dW%^+=;2^>ci1&mK`UMU>v!_r(bf<1!FOQF(|GkUN^ra4{V+oLF$Q(t_P z%VM>JPb`vGHj$+x&psEzMRpnph=5c)S@Wbx5`UYtu`f@gXK}5^o!(oC+ED~0BMuFc z{7f){u*p>U9j-wFd!-efUN z$ZBx-~)R#er~~iKdB@*xutD!IY`PB>5*XxMEin6y?2GaaQukp(7wPm_%zb zTiC`$&2q+q{N%7jo_4A0B+P4D98Pnz*>w&p`y-LVD3e^a4cp!-AZz=gY|``RFK294 zHEA|*2HSxLN6?F}i}Z|QFElOeY;L=dboW_at62}y&g>|0Enk#E*((w^Ee|@E!JLNQ zv3m1ijZXvoO`C5s_U&JSohe$Iu!KaZgoBD+qTX=Y1*}O@?Fb#i1xa?Sud~@Oy!@M> zh< zSRnLZc|nZ-8ZEeyLC?EAreP;zvQtY(dxd~@|MoH7hS!R>+_f$o=I2{k(z>xh$E7oH z?(ac)yA((Pn*rQy9_QuhLIVX#FONT<2Bv*?t0%00ms0n}1|5Iwo;e_cpjsA9cNSQ& zyA=e_Z5z!52tfL7uwF`wrDBOs)A~XY&rc49d-!K_ejogvAtJ6E$XqY4#gG+C4i{B* zQJMk2QeXk-ui#P^{%8bWuj4J-ZS{luwS0NM=*pO4NR`elyzEQh;xEF)kq^e;Axb09 z_wPTi5Z3*E_l19eY80KYY7NBM*5(!jSm;l zcj!;$xUa6%&!6}ocV3aaNuqj>4&M{AMMJWTTpJYLcrBwbS*GfR7Z&RdN1Fx2-k(0A zF*r6ub7%hAIArvWiU9V0P>|JnFVs_X4nPP*=p>s_*noMKA&qS;G%LD!29u0Y48XfQxUkF90Th>eg6WnSw%(}^db?8I-Oi5h?^aaei&5!Vb0*Wdn&0c65^p>p< zHyB(dqwawz&K$Ft}_+g#&n~9Mp971LmRmN!is*d}K#dbXEfxq4+FDl>@`F zD`x!ROeo(Ug++H(BA0o zjnKX@-ks1&q1}Lx^Z|R;d;_B^7NgvO%fXcv`rmUoh)ciUz&x+xxuGEem&hJzS#fbN zkNR}{VL7T(=y0%Ev&U_?3J4~O^+^DC?Jyf&R$G&R=~Vz5K+bTj>FqDxQa)Da`CrSD zcu};dAlAFrfejgQ>u>ONYlBB ziDKm=U1@z8I;?nd6@6!TVXqto!j3Unt+$F$x7p1q^$ekN53r7@hNnWuWrDv zm=FgazLaR*WCChwm@xLKcm0%TX7KeRH@8(H}8f(G5E1)gyBkF8#V`BbS||X|mdEA8SgNmZaADqQNz4 z!N}u;xo1YG^w6D6>g{7!ea7`HnrO251`Ul}f9$CG#0V#nbqR^28zo+Dj^EBBj>c1u zasc7FTA1{h*ywXs?jtDYSDsg!wG=P^qpk*N_-D1$YDG@u|3Mh2#dKU znOIkeV(}?#hU#2W{-SlY3I0rO8cYiBgm+~xysXh8r6pJEA5)_|WemS^8&$?cYBtb3 zOo2v~z$H7w5a&;1^}U;N-0nhc*QOMrJLNd094g@W9JhgPO8e8xlYUX~re&DgS&31H zHI+w^L*`^Vm;mzJC7I}`C#}uE-+luzx-W=~H6`UlnB}R_ z;_As_cz8xj*P8RzvQQNz4hCP6O*|HlH2*MJbj(H_-<{}JXM8hhKLft4vng*!m#9Ka zo?XKjSc4)s0=H^Pl1*BIw`}II@cogJsf_{#Z#)GwljetVpDvvGJU{w5C!Fz@Ixgo2 zAuZ|36__Sm6&JTFO(vccZ@H%PpGmaaApSTfKYZ~WLFN@C5%9ayKpq7te9uZwd8hh4 zGAo`y=?}3!K3k=|g=dW6!s5H&v(Fsiq9|=4xKjoQ7>#kwpX?>+g=R7iM>C$~Xa`MI zGR%mC#upVLP~}O&fd)u35k27u8N)bDRgg>dyp;zUa+J4I?Obe1)shgTtiSPx`bus! z!+LbXw`Kc${w&`7;D{=vj4ZYPgWMI??}vU(q3W3G+Nq@tzR@q0BAJo{&?T2kw#m1{ zbuMR6XM zOFt&GX0%&C>SnGK`tY0*WaSVUgl2yl%Ssgqh!+Kq%PoqUq9pJH&By`U&mQKJWJ*TN zI-hLXuk0a54G%u;Q&xMs@&DRXk+ zP2HF8SD^ST&UwjsnQ&f2nt`g)um0eU4a%!bbf$LExEy!(QbDnE4}%~WipeowEYJL{ z9EEC@YuoZA32w*UKb=R!Hzpp$X#_09)~^GWM>$P6X3j*upJUs@w5g+v0;-K0jB8S8 z3HrLV;z^O^p*qX)d#q?JoMNpQk;i(%+3Anhs;M}|jx2{TgLE~5x;QtAJOTWi%J5Pm z0XG{1I5;|?v#T-eg0_rP*&yFWFc)Ayovb@+Vq#9tS{I9OjHk#o z4k)WXNU19Ib$;*Ia4ea3mtp}Q`O=Ls*a?5u5stYpPban%n_U(r-wPFcN)3bpadNFN zmXFqKi5pi#{-_e*qM_zYqI)d>jCFk&YkakIG>$p0RNS)t0mo1UCisVaOm@J2N!@Dp zRo#>rW3C!zPH%DIB;+ERYs|HMT8K3h%Y=8p&_ue`mr!Wd$rNwjV@RwS$+ zaPaoNYevl})rk%!Ts!x@r87inMZc_>xaEbc7Z|zcpR)|=p*mGIkTL(bA^uDEh6i+QhBq4U{Y*iw9PCvbMmbz zyNa%~bl#GPmISyV+)W9Ke8Iewl3F`1eaxFnM88@8j&g&{D7<2ZI-#K&TVkL%Q}#)E zz~pKjLmZ`?Fj{yXfQ-dt!9cA`M}4XN2MePw>e-qo$_5Ioxd6qstg1jLGb4J+K>=ez zA81hAaD53p@`gI1tpvYS;fy?AJ(~g*VX6n5<|EnoTe*zFYK^jufpI2!Kz<|elk4E* zrL^)rmEo9J`eXPHzpi-3dgw8yAVTz+0mHCNi~(sh&?|B{jLIYTNUCCPnp;>uY*5k$ zo3w4lk@zL_y8#cSJ}lqx4vj#tmzruL~A-GIis=anU)XMx8FOuGl&v=0x$ z!*pOa+PzHdhUy-OA|L9Bhq-ECJqFT7Mca}8ZKrGv*m7Y1WOtWWqJhHb+X#G5qEK|6+Bn5RT zIh6rCY#fZP-m7t;EbS;&O9>2@k-w6L+-eL4boCWtrV91vPe(LV?e;%VGDkiTh+SRy z;}(>v!88uYlod91=)R_~YBdMV`;(^+xjDSq)>ip?Gl4mNDP7m+nE z`iSSTo&~LLaxv;|ihih+GS-p`cq?luI3w=JraXx(r`o)yR#(? z(7&QA`kM8;a?3A*mgp4vZXA%okn1|n8(E|A9PsCD8z9$d{nk8iD{h5(w}A^&l~7Vl z+d;^ojgAjZPO9cA_p8h+up9$BNoY~Vk5&3XF+11Rxc}j9l#Rog!QI;*kVF353YI-- zIJ@(M;;P~|QaczbT9OlP+07dv#D(`seNI)pR6OZe2+dhT@y~SLMugKxe&C}~1%Vt< zuu!CTNVutU`hAy*h|FZsvLl%$8Lbi1(N_atox0!Da_Ua!l$va6?CC*Y(e-c4i${$a z$!opD9t+%w$@I_%DN<2oHu`P`Vm@w;@tn^9cNJ%{m?1ZntPRy>uurL{TN-ip)rQEj zXi>kPDFG?T#jztpZ1^LlRbd*9yiPFV^P(PCaus#Ic$;?AR7}q=;9MaA9KL~e^O!5Q z@N$8=hPHIn>pK)L(hcQJrc#^!t(j~QRpl<+dS%&l5xor&nJ33Q?H!9>3Z`i9+;C>& z5kX(ded-V{3$)-Gi-M*BXlMmkHtYV{n-G!bqP>Q=>g@NBtr2k)i{ zJT#}OY_7=y#k@~=G}8ROW{3MU-zRa_#U#|-#@LDEDy!#q9WC*{DHx4P%A;g%l}(Ed zLvfm{Nl#8QFBKmK@KrWv?fV9f6hK;7E&p`9HI8+ypNz_E6Lr57^xW6NA;^2P%RG5X zScTnN(cI-YtzJgQ>_Oqw`qe7xDJ8#!5jVqh+--rM8!|=7s$cYenbs-3)oPn2f_|Ti z=~gwl!7{*28M?Si3ks-u9ppvx39yufd(3&v8nZLPAqKZ7 z-&`hptr$JH&f%i->ED83KY;k8KT_P>m`Q{fv2Z~q1pV>idMHbhE0a#pXOeCm8)fZH6E2&rpFj$c6@W->7+C1F}(@GD5W7#1wJ>ny{8veP}e5uI>S z;%ND8^{L}xj&RcM50M+w8HM0}znbIAxP+GST!!c`rrCo?uMTknxHs1sA5e<4An3O`6^ zKemy=RSBCP3!d6mI_T3{X!3eVAtx~W7?E;Rn*x~%3R)A9<`5lE4Mz2lMd25{UftC zt{s0(PCbL}4h_Ye9<@;Ju?(U8-sk@?oY~UoYG8McJX0u}J861*$`^+HTzUtKqvVUQ zIG*IdP77P8-VHK<_Ts!Jh5vov$2Ab&dmJTdvf&$8#`IbrQvC2}QYu}GeBkDPf}@rr zrA@tti!tm6jLh@WfLnwJ9O4u&EH2LXE(3wv;j(aH%JD|rE7^m90goz=!moZT{)F~lAUls3+!wK6%B30Ov)MUu(FCYBW6fC&|5&anubwF~tt z#TXVqq(oOFc04cObc&?nHz9+8u_$e!GuAR%ed}Nkks%`o^vm-z!7~0+@i8vu9#*i6 z%&LISXC&F-)e!1&Y%4EY1t3;!Q+BR=zB;o?kx{~!p=%vAoUUks4zsaG~OzCtG{wozB0 zFs(0WksrOJg_hULJ|=vzN+jie49KGqxW6r3aichQcsF=u*cdczZh~1!u+M&ZGNP2( z+@+9$WOqlhTLsgmISViVzApw>TCg~tkoU^nx$wTf(J2X<+g&5rsnID4x(3IKw&TK+ zSnxoD;uUa|_6R`V%Ne#~#p1Njy*G(8q&bM?qF#O1@RK$A8>lzFz}U+RJBFq{O|Z8C zKkOZ?gGF~jQ| z`iz3|KRAapmG&fZOARb2=4)O*eniW|_(sU5RlQ}~CVnmrW+-(?jchFVb0*70+2R&7 z^b{{s^DYC2YXco`wMX=5K?-Ts8U=^3vazvem+#QQTi6^gI>v^%us5+~ml_p@-LdQD z?fihpwEFH^N{+*@=$H{U!OkZqq63&`*UjINhS#w23=6ZcUI~fEMa)C*^F;b82Zfuw zm70*sZ8~kQWVfBK(*q#DFI%>$1Ke~s7l~rqvwq>>Os_TXp2XAi+*XO zi0P|g{8ZE0S2Ih{piUqcui2j+==}k61zr=HYf$KFcz?!sfn;;dxOTd>1i3R#-D7B5 zaT}^l4;Re2Yw9ggXtm$=x=CH-u0T7YQ=+z;S?+wE<9@5N zV>kcZi(_F7(jW+B833P|g4i07BvMOZlc+=xq*L19N7L1nK7hk4JLKO3iY4nlvBSRYu1`v6{?cT3UtR zFA$IZjZ7zqY7vI6q6@3^>Wp6huZ=ZrJH-C*$9ZbzXvDo<_P*{1=h^oCi(#7?7>&T? zHXIDxWl3P$p(?sQ6!L(*9PKjo|jLDFjCBQRLq=(>e0g3npBoiwZoDJC&j1M3?UrvdsnJxcV|cm3-B11JqL!IQPH3e*k;f;4=cVaie|G$*E8-^$1CS>Jnaf^kZ~wT*Ppu~E zUVj)qc8|TAj#i&%>%c7D%1Ed^3$@anK{2d%;NQztl#VRF8eW;7=L4dHnywH52HtB_ z4TRyn$X$nA?>XDeBRhn4DbFmqa~U^~vcIMaalawRYlRu(_jYN(;=z!{+0aoQYA?{2 z=Z-x1ADWeLWq&1s*`Uf^)%D~&Hk@`G01LwUGX6#^nvE?s16 z;H#0DX^$8I^)_wS&PX64me^7NW$EajVhSzsm8y8=*svPp@6 zrckK(HY{P^1bVRpf#OZ3L79{COrMqt}=j?qOaP6xhLd=Z{L%^5^E}%8iCP9Rblp5kerD)iYE*qWowzfA+e#a0)tJ8 zxg!b7Bl&EVStr4oL9@P&u^iI(G zWhjxL7rOnIq!Xuqilh@Fuy(XYY(~p;nfMxWH4DiVeN_huEb`nA${l?b9;zeioC2&f z>Kp^CpQIDL|EJiaJeYUnxjR@sNhheVLP9sMmoX>Niua1%cpMJT?8|J@pl@70rq;PV z!1zh?`~%~y4{$DmSO+22Q#))d7R7H_A5ONax*u*s|5!Fe(73Xf$S0E^sBKYCNtUD_ z*`Sdicv8QTgyFqroSU%U9{H|iR6orc<*S5pM7^8VHM&PD=_{^$M0>j2HM)z7@s>K& zW3s@Hpn#aywk6gpf%4it^gG5F_Zmp2EX;o^s>1$YGI7#a?5n(W(^#-|g^})& zR?48_xc8Am^Sm|j(_6}*=Ggyws&0jl{?Q`pLv7AZ>?>=zX+^N8;ET<=nM*Knx61&! z;RpPCnn%e{AeJKoc2%OQy{Cm%SE|-u(sB!$itDKs&)^}ssOiLebFtiu2W_9&A^Ipz zX|KwH=_e8=VmnX+x)Zy|oJs*VdW1X{YD@m-75s!@%Em9C7cQJs`) zo5kzJ&7T+!X|_v}9B1gh)vdF;XY@V&yIF8?<}NL!jlvE6^ZFJyc9E+P>{gu~JwwyY zZPUA-w`&62)I^kSl{;Ar*BhJQ7=qKg#8Ke~YZkO#gPk+G-o>&?Qd%bg3mq;1SnQWvTVQQZ@CzY{A< z$h&1`SvL5lwVXS{rPXgiKcTq`Z( z{5f6sOfT83rfd@Vig1;I(FFo;R!D>>VHY}fjnM*dNm_*?Pbq6;76i-+b$u27uu z!>)Oz4(A&G3Ma~61Lskzc&g0n+V@I3>Pu1kQ6h0~DDuhtONCq;dV%r!=S26+?? zeTnJ9#ou=o;r{6yV}UcrZcg+PRXXd+q8A}*7XFUuIfc7gO=U(cZzO*}5qt2Ou8(ft zcO2%E>Xn_v?be|)0glxtD`(VL7}~5(tw$@LAb)@n1_C9xBf(^on~?0eU~45&=z~}=A|bMSg@DsmRIud{zxSzjYCen=cM+EYn@;r z;qt02>Jd|V>jIvL&>9w)P;@%7i;U%7XPFwAWu!fTG>He}z$0IQw_b^FU1vc_WwymG z4AVGH066at6=f!nEJin}+UZt^yFn$EAqcM_4_#3VU6pyXn#soRVWmkseYYc-=n|gr zxC?sV4&7+xndypFhu<*z2(Ft;`6*hg4d>TvbN zI=geXeP1JF-!$t}soQ1Vn+hC>e%gNSq}%I8#D1Dn0Yk(l^jT^9GSP5$e~MC2uYooX zykT@&0hJo&_(HcXpEH6qA{5a2h3J#bbMOh)vwx4&Qvrcd6Pr_Dd96+-;`T|)dP@6i00?&!V}j;7z!3R1tc|LjahnSTbYSa}Wt zYmzarO(7MEH?|F0A}?cA?-C3Onl`23P&h$XF-NX^8)!?*Cd2{H5g~5>GEUN=?k8-} z00DvN{3lZO-}H!4lu$M^7jbiTad1{Pb8)kERWbW7kBD7tw>&5_Qiz2MF|>pb8Zrtv zIy_rjU?fan-Y+0Mq;3~m1j<<78^j2W!fjwrst`ozA7HeTVk@mR zD9sP~&gYogfA!J%xZ|dDH0t7bqPbj!LoUjF5`W03{K~pXo@knc>ioKqfR|puW+27X z0{%~e{-X=z{{XK4TSqxF zS0hm)SEGM1$aZlP@&F+?v052R%bzLWC^qVK#JKL~o@i<`(>suVM`6k-GFVuJeQ=}v zfCxh!sTj*OaaIKyrWU)pd#8Z$OoUcEdPdC|1_xw38&)q4xUk$GM>ia;dXfqGD;naY-hRMl9`!Jbx0@ zFL1qU$n$4J4!UO`_wyH2Q9wPllyseG%vAf)@3-_9_nQM+Wd1^WVUOLxS_I?bkB~(z zO}mSBZR<;yA{jC;`ke8EsxX$@%E=^^$G*e8(7Y`6Mmzl0%$kiB-lh7DvUT{* z5ApaF#xBCR5llvb+%GluD*n633ddN#K_kM*hf0A<+WBukT{+8>(-R~vA;tKwHJdh+7gO(+DT zA>i2S61@0u+p?I-d%^<*OEbO%;`!lgVK?+7-&D7|wCOcTN#rKTmyQR+*zCI=k;F&?Bh))5B2$HL}! z3#Skp7ulJDm!C_ed0s;aR!d@IAp^}o1BuVJ22JvXOt*Z zCfDK{fTkr4W@GsIrJM(R9u3#UBy%rx$jagfew2nmUfN-HSk%DG!o*w$#Ec6H2?_;d z7D$E)O8L)sgq{N?A>g~>j_>P#*M#W%?*BEr{C7Q4_W!EJEnZFrAcPdQWo5G5;-@+k z#p!S|)a`kvt|Uo~_UpKR9%m#SrO~Oe{IT}uHRN;Q;08n_7~lDM7vdjQrY*r-1E47< zQLb5vl;Rp&>o%_mvx13~E?06Ium~pYvf{*c8f9*OT}NZ^j*$7Ul0$M_GuDf+Rw#h@ zcWx#_ch;ZV>c@DZfp96bm@BA}Gjx5_tv@vaC=9s$0Za%M)pE^~&fHpBvDHQoURNoH z12(VIKlQrVZtahMZSPtom4@_->$fAFt&#cU9Q-A9MGBa4(SQaS;CN-gf8PJx$vkfw zWq8#74z}$b>=s$}AoBZXKeSseY1XT6X&nFK1VjEG#FI0!H?lBu{+EKy8s3Vk%lMxR zZ*6r|O2V>A$Ue6i#VBsfQozFM$Y_e7P4{O<7$XN69+OtcdVo*jh)$1$_1I(+fAZ=E>g}9^Ta;Lw126pT(!Z4s{cl$Le); z#74XE`s%n=wW>@e{+fvR6&K6hMxR4&i}EIp8S| z>4KkZbSU8#f3uH{)^*=%nG$9WaGU%UqH^Q^4W(daRg#fViX3B>>qI55eu$lH_F? zD#T64o3`*Og%|@@hum#BlGCVDNuIGb#S<6MXl8+lz3nq)dOgHbxVamXs}~o-9l#vQ z#cB_onzm7dsW^o@mSS9=`ps?+YMYjrz%P-auOywrzA7 zx1M+A#(ejSnK$l4?7vT($dfzI+H0>|>8(teP#06JrRpH!y3f>?tO8{sYo@GFz<>BG zS}CSRPiEs5$Vz6RaNGlCrA*I;c@$MixdEjJ^J=4mw8e!*N*X^_IBz8y0Gv@HA~0pN z(14MiS8k?A?`i6&v@a^B^tX5|T~*FLUX5r#9eSZ(+VpT?*I&9@6q5++9D;Ag0;fsrreKCiQ__l+d!~rZ;{Lu@JsHnI{$r;m zFK0r*HlpDYtU-`${SvQ|W4Inm-= zseB35-NzdOx_{ni`4s&^#oTKebqH=D9b=;l^D3#ImYy)o*}g4LxJKzhN7La~Rk)=; zqGFH1QP3oolnM`@2CQ;m-amOw1w~CCX42)%La|#CIJjNE1z07-t)#<`#HT9s;*;=J zC4Oyq$ED>EX+m%R6`=!2FyM~|E0pPDxs>4Wn4V94L|+J#COTc*q@OXdNz=JIhEjoc^we?;if$_h>z?eV)iW z&d42j&|Pm!J4%(Dj(P*gfz1MXnS|Ppjm6f-YjFK(M znR5g<7=7LW1^D5`;HVX~VSPeScmYC*T?5?KT<4M%QIN*?I3G{HtY|%(F2ki{E=qL? zm{A8iO0Gqin4J)dpC1v|Hdn~DNy$uio&#klxeHRkGs00&#gre)*@rmw1Mj09?DuK% z=}=HT#bSGp$=Tw(`{-4H4HJ2668{|az>v82BrJ!;@%@eEqu`!hiR)%RAb}!TC7; z(z_|z2=^Qn=VB5Fe!ogwub1jV2A#%HGtgJ;1usVO(r4@iCq?(tr|gZndBgDI`TfE^ z1)6E7$t^P*3#y@nTQlVFe!T(7N z^g0G=Yg&Cf-v3&T((R`NTm6D)Qy5B|sP7o->~+AuLs zj^LJIy4>_MUnZt^7wtVCY|_Mtjm;D{ola^@o1-qOV+C3e)wsc&w|*~ZzkY?Ke-`4B z$f=6^%*xDosGO24+5OPB!z-ED-5POzH?P7&a|yvKwuEpu4q|5-GQ=zoM~dRUNH?WO zw@$dMchCl+d-Y~n2dbSTCEKbq*@)*vBAcsrA6w~0t;9i+_2?l@N^^U6+);P^1MT4l z_@OsENz2gHwbCAZ%Y8Ls-&^7{u;jae6S(PZ4KDILvhlx`fl}hofK`epf?<<1;Sn8? zVHepGhdhP34fUbQUL{Imy0)eiQDIS1y0qqW+XeDj-KD=6mjRUiO9$tXnEOP?Au=@y zQ9SuMhC(;yvDp&4*!U^*4j;^4J**cZu=mvFc|?=$7>pBu1AE_vtInMw@%4O?0xM;K zm2!NPD{(GVtHXF;(wBzE;v?TbhYy)Qb;YZYKYlc#|2v>f_HVGF+;j&Pe;( zzrV!o!5j(%s2!T0TI8r{^Q9@b-?3y#Y9(q@=&@(~hUiaP`?ElvQ4$e?YMGNOgYf|@ z2P|}Qd|?WjVRg2&guIrJz>$Zot;R!X52j^kDV*T0&ne5d6bVI3WIG zb}GhY*3t>xGwPAy$FBT|xD)x*PfDJxr^6(ud&3_BJ3I1Imo&S?q za*nN)?Wac(xu!B#67(bN4a8U(^G8oj{V`jb?@tJpx^V+xj?2}EoZCIr1Ae0b(T>tY zn|$5sb1d=s`uPlE=a1XhRhvd0Rn9nWQ!H#T*4pwgTvKI;kjE8Qtw>(V#DF8m{?{qW zuEn9kh^lDwQC-9H!gPXvLmK8+u?BvcF&*7abFF__;U-m=L zJjJ>x6|@hN%PV+bRnpu=X6mA1m}Sm^`YmSOs;By&1m7$ooQsJ1IGRPj$BbkCRN0>YJzXAf}J0ZHU#k83Q!} zfpHw=sExkBPspDHkRZu6w8R7$iqK>k^`m~1*)`}0sEtco3riN(m7$e$YwCmHXb_1d zGdX?t58Efcvlf?Jj#IQ5Mq%&~pCNo$q*ft^r-EWgS(pwWI+JX`u<|~BqSS--yy5&S_)D9|yO?tq1nwB1C5qRCpF-Qy;0b$?)>@uT*N-CUtX8!%ZD z$OIs zW91jF1`LRN)BxdhT840yu<)XFQe>)j3DdQyGywI!z#Ip)InorxQ1D^N+C~RRztztq zNhuASIJ9m$`9W(bXF`#=mgo{<2_AL{TcabViymYLf>Hr8oeWXV^i^c$=-ZY={K1xu zYy@?WZPn(uoEf`tPO{2K?!%E{2Fw9-qoV_d9WPqjIw3g;+d7T?4j41MK-#lgC@FhP zd9>DFQ@=Nfd!{(DOW1U|lHys+dB(TxGqiX|EAq{go?XnNN$xX+Rnauda>^hFk;ppY z;Be7z1QDk9MdliiTwjk^m+|8bKLRK7>LjCt0Hg%_{ zkx!4ACl)be(T@qQ=SNS$t>B}bIeVrm&yYT}2-O3fgE4f1lgs{YnAOOF%(;EHR2Z#;pr6OM8Ffsz1^0#?Qnv(8AoV~)S6i=8; znsUaM3OS4psq@*~e8#M%jjZ~l0^N?EIWHMJG%{)!P2>z57AD|0Rn$^y5=1>lMl|o% zbzqWv4rj4QDcsxEQz>oWR)VbNE(j^r@K2If3ZDem2IP&@e+ZZ1l8Ya=!<0{_-{U_lx3Q3#8+K=Gt5NeGO#s z2!U55$+0eu3I93N>eQf%33acAb+#A1fD$?J3oA@_xcH4VnKFwZd#$ggiIR&7_cT5$ z7rRbOm%VE05~t|!Y=p(CE$s43c*jD*oZs47Y0OD%Lgo8~qDhM`sF{sVFjN|Dzp~-& z*#*&`wt(pR&R6&*hkL9W;Fg_VKK+FHw@zS*!EEyRI0Fh?-SxkC(x0@&)|r#VI&g>_ zZl|0t;`UXrs)j6h_0P<2uwYes+4A$c49uhM81o$(5(L}Hn?n4pz3whd%;fG|=^hKR zTs6U8?Q=oKHJSAxhLxpYLhls30qP@O^W7{ z49clB-;fwx>EQBW?9lm)t-fW1V}3TRt!6mDrt0-TevIZ1(3>i-6zWRI>ybf0fy?_n zKya|HuFUu`c^P|6_yG3BW0q|$f9~yOvHOO_;{W`P4sN+7f~g{QY7#FSRa==_C>(yi zPkapmX%Y8}H2Q8UB@ZuO83cZxdKPx%m!v?+M(*JSjw_GFW8|3s&_MR_gxE*FTe8C^ z$Ib;+(p7gWQT-Ab5@X?2vW8WBZ8yA*;GDxTio4YmVa8?un4 zfD|jNSEi3%YbmRtd@H0YVXagLr__M2)gUY&a16f6X$uz0osL;l`_A7z0`_e0R@S+n z(XdWUkhftoZe&mI%!zG$_0v31US;`xIM21=50zWhp$tkq6+p74d`1bJUO=Dl9d=f$eAKldR#Gb_{x^$^@s?nHO#AyWr~`mPwcx(7;1@|SQ%ZV5(rW$>IjXYrHW(> z3Vy+33uOxW%~L$H(RuR;7gXuN!D3h}o7U z*;_H{jc8wApDLTd0mj*-lt-FV8(e=hHR^vli46+6SS0_cJT!*VRbE5EiyocZOwFV+ zvZ5;1JSDhP6P#cq=!;t!f_nD10^>kXuEjjC>mIg&E@FMd;J)LDkNUI?`-zBwW(;Y8}dWLY>aJ+au1% z{IEK!UX$9WZZuMb-Z7cV8PNx09feX!v}*>S#W)JMlvBRmkw}gROJ_qJRC<;L!OguG zCv`{z8V%ml>HA}IRO9;h^`JuuXtecwV$I!=Jlr(U;YU09q-=lPg`jkM80tl;d>Ce} z0A5pSR&*5hYCa}c^Q{-?;|=lDAQISO{Y9@8y2jZnUkSpJr{_Er6-1S1Hlq85kQ~V7 zNs&Zp=H)5;{ttLhKeEqJBtp(Ew>Ir^^4A&sUICmvKRObTO21>GlL5s1X#DNfBI8Ef zVPc8lRWqayOd&{~^1Uq$ZYAF+4t9aL18%up}H1m+NFe*2RbB_c;c)>z}}+cP0egUmH0bK^rW z&tgcRM5h5t!Rw;sQ`kqnUXzy3QeB98R=~5b@g+%VuH4WuDP=-n%0zUsKg}!H_#_91 z$yHp6Uf7_cLon+RpQ0!}Zrg8)XbXlEUa}|H5T|Vvlv- z^d+7bb*@=2FgR{fDsJzRega8AwOR*uwx2Q*%8cLSSem^uamFn1ehbAO@nBgudq2Cl z*tvrWo-oWEYfcS)1>psoZ~YOV_ntTh{m#H}Jy8pQJ2O}1X25SSu0x1lA>U)^^47W2 z*XjAW4pGaL0A90$EkfsN=X5JB%dn@_3koKusnfN3zT5K$rd+&7oSz)Wg=jQ_yt7Li z4%h+9wN_f<_4t~Y>3uhy85>B3SILUsf?SgdvdA_{{6%zg2Y*qDbj*sAUo7l}h}H&y zScVt^qEt39}M9T9{esMJuvXcT#($4KQ3OsVa?22{f z66F_OWxPkQ+!0J2RDyQ85g-e^_?T2n5lNiRYtvE~mX4XXp_uWHn5pfk zQ#zPtCpIL(NW{){HjG2tOZunv=Kyx2Nt0+gn-rNu3Bv*J9DGsNA+Zo!eeP-5L*?Oq zW$i2(%jq#_8t8$pN9`_@RWSxCJ((OuYr9Qyhk42r2Yh`Dzp-1MUZ&zXl^ zb)xre6f|+8p=;-iif;>km`HduR{QCiNbnLwQ>jnBu|}77fz6x|SdkPwc_AS(zq8w6 zpP)7SiQ?eCEAQ5GeB3K-`-QoEB;dnWg_Jl;C8J5h%gjHM(@zh=;@3#RtCO_LHNyFh zDqSGg?`o^2uAhF2cls&-#pi4dL(jG|=4_>qoZf0J{+-$Pn87`!THuIwLWc;cB0_ne zAS>bTcR9T0(aB#Xe<7!td|Z67x{kl>wACN4HeKGXS;yUvZa9+?mjZt+>O*v?(eu4h zTav_WQayjWR$k)6_=eHF-g?h&VK?t{_wl$l^Dj|-$BywI&Z9=#Gpf5^K>y&J2}7F1 z=x?0k^>1;`f2);nF#ca@C0PDDtn~d10Y`wj`8TO#ZeuE8<7Dh$W9&dIXy9lpW&EF3 zib;wxw)6Z5-skN087=rfH6`cgfPzTj`UEXN2_Z^Ll_~ORkVH5V=ZAFSWj3ALT>iYO zJ^#$~5ZDvi`@J(3BRH{^C)neM*HM4ZeZSRF+x_+Y4%&mo4aPU8`t8>t^^)w&^E2-$ahe7&UgMG63afqF!51vnO$n6{vn47 z4hm*UJgEQVwgJ$m3GM@w8r=ofSd=fBjHp;zqmxLZ7y#x5*~9m1=w(19f(4tM3< zx>D?C$;T>E5ZPpt`mZdPq2o0*UGHHXMI5vW&WmR8_7`=V8jXla$eFEK{57s$WMpdh zqDMIUMP#D>yr~Js8p6np&}M*UZTgnFmMnPz7sDyoO^+9;iE>jj*~t6?k+~w}X4ldW zUf^~6B2RKB-e62Evv|sHMUG0s9T!JwFwqBEn42@#qR|^#EZv}1I>wwM&s>+(_JrpCR`ChDgni&>`nS5q zrK26cR-fFlMW_UJ98+raSV_-PxD^f@-s~|Xb%-dvG!BZ^wD8zbttRxGc>v}w4Wfxb z(u{qL29#s)>N|#cW|0Z9?T*P=QTm#RlOw$ey14+@=>Qy&p&Xjk=*v-dbnu zqCIUZv3t2@GN07fvCl$NzAH6uzKEkIE;h32X{ZMdppVIr-_3@IH-y>$;;6YvB zbJ-Spw8qJhS!KBB;LVlDgE99@fjuS-#7X;?yQ}9qGB0M6ohGld$&IWSyB0wTK}L1C z6r=T3!vwwhspeyHtTD?@EpGn$TvafMW=H@HIItZ>Yk=j! zWZ9HDOb$q--%VXe~A0L<5SV}RH&5Ph~z?mPj&Xh@vfL4LyJtX?sf6c0O?wY6e zc@bxwqbBzQNh2+vd==d-R-Uq>%EcBT`yed`fPwq`%g{a15CSIrJJFB+ZKCu1FB1Jf z>h`yw*Vw_>24MUjw*pDZmlnth2s~`~o5VUY(q*camX)(!jhjPg!irEVzY;}7h!Eci zteV(PE7vzYT$^_+pMSn$2!@})~HyAo99p-ImQURo51J5D=Qa`}o%77S9NUc-@hGOwfQ+rdLmO_e$U0=9hDZs1| z=!Lic)UUCdqNcl#ZKLb@MCCD4sQa-75xvuZHM29EZFFXBDwGxxMM)ze9$+9f6qx>m z7w-&;Glma>-L~YU-Iqjy)HYV9%O3My(L8zp%;UUyR+iE9c+OnnE|xG`VP1 zWxPhC1ceGu`xiGvxOBbv*gl?N6-8(G0a!w=v>01Ff)9yx7%L37#5WM4PSW#Ng2Fbx z8}OPG8cg{?rzi?T9n;|$Bra7Fo=LYsRfm`VOSM6hfGO*QyBsQ?d}YkYE;7T9h(J)({C1)KpCya`8(5)iY;E^nrCCWz z4p{-^)5e^l0T@)$UA#P39RC+;FPWqvBxw{XK7#Z~@VbLJc*wU#nx)S5cq(USC<+^i zf4>iZ$MzP!MV{knY6gP{lG@~o!*S}P>w6->+jaH!j|qcp0^8L_uYQM(bec>ZBE3ed zINuXxXYavA=XzCU9fOQMJUvvds9{4o7?)@%&?^Y%(kO!yKFIm?cNSCe97MWEm*5(B z$>i!V0_9c5pne2$bd0siN*b{im6naW3i~?D88=aM7M0X&Wvli?7P7-{cvKcvyDnmkl`Z*XZTjs#l z(>!`&CK8T;j^0Vltv7YEv!UXeW8(;LImloJi6l39BqIh-%E(~L)M$MucdSy`X;#>^ zQhJyik07irGi#_|bqTgX2gee^3l&|46DhsXG6z7^dfUTCj1CoTb(cpUc2_m3jKySr zFRmCIWt}0*Wtm$cHc&wWw7{$9+6>WhPz7Eq_1T4LN#xK7phaQ{dklV-BNqE5(#_@! zAx!%WA)r|Z-V+mC2 zv3SnHa1`2C%H)w0jn0HtU?e;KcW?~ezC$^hpO;W}GKg?)qcnZG+P&<9X&cP=b<%9a z67RMHqef@Yj9>oAsAf}Awthp9%w>D_MLf9`Hr?UWhn~XMBPne2@dv$-^FxA+e}6)% z$T>WIAXasIVe8|6y|1YCw+dZD0Cgh(F31*%1|KL=VIKmNP_a|_8%d}G879aP8DRE; z=?FKGGKQ$5{LtWCQRB7!={fxe1Wd{7Hi?-y zRflxbRzdx|wz9orB$#JTa2lBlN~BI;oS9=TCRqtg1e-$6p>!)St%DK^W)RuL&X^G;%&8D5PTkg$+L+YPL=YI>vl&Ax zN`E2rFW9n+ErSpRtcxE<0uG;0HVVWLN^jKUUqr)jevdkWPM z3Q*(Ji5JCP%gVNP1Te>(+3D4G9`^NX*2EtX!C~(~aa1bNZp}H-a{B@dCr15XOP~{F z$r6GoaTin1drQgVKz`my{uPM_T4Wkb;XHsTR$9vcU2Tz{y_fNz`pB@lG<_06}lUjl-;->by4j6?qb3H(wn54yFwl&V(L zAO2op%UMvtTYY@d(h0bb?l!nHQy11O7ky)<{@?`Z_Mk}@g-2>Tw&{bvZf02F=@SZJ?;j5A&4Y7g^ zs{pmm(OP=a62u`%NDybShb2aX%xP+?`2}l>f}Y-SSFZ0;x5JY; ze|Tw_HHfmja261#cncD7?P)geR{#wJANjY)T=K@~SyrIMW(B3x!;rKGq1&G(YGA74iKotzq6xwGVz&&K*Z8J-&XHK*a>AoF!U313X3Qp}nEN@2 z3^v3{m$#|f4?FWG%eNF>!8^`cpp&TArxIfg`{C)eTPXFh>k~#?tNGFydZk7d4Y%Bu zLo+5GDvIl;=ka&K*c5(s=D@*gwHTv#<-all^ZjbKEUV8Ovci3F#0vU#+aw9zcwGeY+@N{EwzWIbgDxUb3k!UQl@)~* zbopU95PVu@f)=UKiv8L`q%X&#beNjhN+@qFO^2nyxODo=%fl z;W10=w3dt#PU?_aoa0wr1QW~dwRQZKoIZgx^u{K4L6uW zbIQ&*jHUaww||(w0C*dLo`p%-`g~%p_1cpGB?nsj2tLEV|5#*ijrhib=REGTvy+QW z*QLq2#Ka`t3IpMd7l~%II$=SOpX=RZ!qH`yoU1NPIqr*y%6x?twkWj6+LZIZ!~T&= zQ1@ZxSAKjgk>>d#9Kem+N{y2w!w88sS!_CL7BMvO^vGS8u3%~_V3cYa6cTj`hzlKY zH(`jmE|urQhe~sweHNl#N`vKD7iC&@(*&SYb65~3)U}=9-Z~K)RfUfPY!$n4CrOh; z3Y71V*^_o|^*Wdnt$7*F)qWP3_)NX{PfSUz;tO>dx85O%p~r>8a*bIAGgO;^Ky#Yz zwi!@wL`Y7RafK+*zU%!q0 zxa8RaQ7tVl8(pvaGqA^P0_VFdK{QRRSLrpea9CXP=B_b%U$XoRv}^FuS8Hc$BMM#K zQ?@w}s`JHxl^({=Xl3kO0q}p@frDC*MOGqSFnSfev?QFHoE=3eIodE%zRfca&wC_; zlu4Ehc&bz7&R|#m)U=>vZ4^8hf@_bE9KuPSQ??ko<~BsuEpvEJVej5@vEvGwvH6{2 z`fZ&$Iv8NYeGkqVY{Um<#Tj^kP1oas$&gxA8}KmzYx zKTZ@sh|JAS;Ht64u(h5+tqjn?D)9rNSu7V?c;En=6~D|x$}qC`mGFi3|B2>-Th zIoHywQG7tv0IeJUAT1XfX&&}=U!YvV)O-Lwr|MC|G z?1s8(FlY7hU5CIEmS#&9ha}r3Ob%@y_ZcS+^_zH)Yb>3WfdX)}Vdj*8yc`hQyWTA^ zck#F@3DTnvtSl_Z*;h()k(tHRu84PWkeHU`qoeR#vSXaq(fWnnTjpBI3J|- zXWd`}xXg*;$*C^6@gAL}e<5(<5Td8EgTC}d2r@t$8?qijLN{pQ!aeGh0mBI-DS7JT{KP6H+B193Webr2BzKl-TG9wEd-PpL zM(YcbLb#EfhhUTz6zMcz3*t$Fg%eU^3~URA3Yh&N-r$;|xt|WPl%SH{Q(A>LE~TQU z*5suWd2mu_3Id->TI)Is$EOUC4CruAh)}xkP`1;>!m~gr>Y&XnzhAY*k1hJmanvFj zHFzA{6(z6Z*_6Pfj(#AQkU0K6op&hy@mHrblj8R^x%c6TO;L3$jgV-J!PH^tBO=b( z!_1%B#n+XD|9AFZHc7Amp&}pBBVSM2)YH7cNIyWhF4T^gaPBoJ(-8o@l#2)$ky+B zu^%k2*p5Z=1-|riR=OGQn?#Pwmmt!8_zzrH{S-ta=M|6(aQoZsAJNj;_ODqXyN_Hh zgtikdXmQ*toeu!mzm)|Xq7p+c<6+0CLAv^rz6ugcW}AtVSOQ53L0F@a7D_}El{!&{ z4RDHY%0qF%-cjc)IOg2vN6{D6jszKm*hG!Ln^)<_^8l>o;VZTsRWlA_RLT{;zqz-9 zT@Bi?K2W-Q=)S=JAr=j0c$oOU=O=Mt{ks$Ff78+nu>B^+{~^Ku?-{d6D(i~aVhEQ% zK|x~yR`z4JBe@o1tm(tR zURF`=9mMW?C@zgufZe^e8JYu3G32!V*72O!Eve`?oBz_s8*tdwu$FOllooSY)glGs z;1yHSR7+|3)8304mkYB&>Md1x!v+IocC$ z8G3Oxjv#-Swsc$g3&dIH9?eJowea}Hh&oUh(DB58zGdmLF9u}3$ql)Z*aa1u(HjN1 z=Lw-HFD_?voKL$DV&lK5{xq`fvZfyA%#zj-k_)Pq@s83ggxR#G3j3Gh%zGhNa_Cn= zH3}TH1f>`dm8LjcrRK#_1ZUFHd;i}rjXE6?&L%67aa*sgtNZN??tuVWFiYhq%>m;c zXMXU8DyImb%^LfVkO93q5@;>%QHs+MzcFUkg19(**MJch^0nZom zL~U2?!sxbOM*SMB^mrtDsihW}f|=Ych^Q>-@IyC*72LDtjZ6e)zTCEJI-6BTuUg!5 zu*WRrI^%dQC(|VMzbwvRxCSc2Z~}sZ9I+*(ofz#>5y$=E(-)YxEQ&$#*!EP$sc>*` z^Q6?3SF-v$EukKZ@`%D#=~JCVY_ZUJUdyf0pFOIy%P=IH0PdBz{CVq7d>Vz~C5lan z$WE`}xva(uF>@FxjcO;;N>4AgMpci1N9?&p_T?`O`H-sXLB{;(%MjAS;B~2;phU_& z2`^`MUX+YC_6_Fs#u@^5VKzAH62WaA9i$D6hL-g3#+XC-9hd-$kr`Vs-XggN&ER4% zwBG`0TZ~3@38sk2L)_y;*{Cgyd#zCA4}Ck1Ek_qv+9llHARUDzpsAV$KlFZ7NOK6a z(CrQ(T)BFr=app8dO+K7d4gY&K4#bJ3HU^Q5K7bhL#_P^A`g_ zt?}(l+-@6jz3HsyBOVdESy{zLhU6pp%-KaZ&6#Pcpy^ZETOq8XcxJgL;|@3`YV{33 zhilEIPt*s1)S44De4>8j5N&g7|DM)IE1Tka`fUw3L1(PKd-8-l&$$MfFEpX52hOQi5BH?8#IbTtkC_yH7ztea zOpXAEIZh;YDpL(y4|;6<&=;C{KugWDZ?hoveiyQ`;YjkB?OYreZpLZqQn4M&0W$e7 ziMtqpk5E!^@ID5iLB}QIa4Njw8@Z_x9W)NpnkMSB@yT@}!K8 z2T}Ls`c3eY5+=>!*2xmWKzP_4W-JjaUeY`_S3cmhw1+2PD(j>ID)Gd8B~CSYlG;ZjaSo^}ahw|^fIlR=LN<%=tkf`7 zI#K_Yypli~RYr@nTlpa!(sKCDHVitLdJ46~5EDS2Gq*I3=_pn8>&tB(M^%z+!7T@c z;AZf0)LM8HPpp|oa5Y^%Z?NHJBod#=4qJ!1&m)n?&jWJrLJ3Luz}sdL-!T^clq={u z!Fy0xrkNyj{xpg@7ROBDF^YW0dyVSDbLbv%+2QR3Uns>f?h;BpK6!9Aq7Ow4$Le)o z<0!#ORdG&BA00zvNoXuUAz2Sh!fqg{AMzD5xa8Q9L4UgKx}{=dCJuRG$fO1L`}9_x zSMzs|J{q+(cf?oo5ucL$d4!wc8im!l--2J|tnpFBT z^0B}zck7}8=(>nP-anYp{0|OQJRh~74FP4{2o;v`XS%`*q)zST81w_yTWaOZJyBbJ zdlDa_MtoV>!}~8HMKl@*@Q4ZMGZ0u65vwbT*Rr3xD@p_T?IAD;p_ZK&wuQ{X4_1ch z6m4KSoOVfAE>YxqB}<#X(g6>p(Fvg$4SZn=gxtaFl9CL$o-17}6Z^>V%DEkK6llFd z;fg}wW-XNq@ss^jn?=^E+qb`6hWzQ*OcNp_bLi_%MZ;U;$P??4l13e*)<9N&SDsA{}_#FEOP7kZ!ru?%i zUt}R2y~jZ^I#dG|v!I${7(B)Z5CYI49-fM#xyOhD5dV^X-kW;^k+k-_TB zW|SuGFj>w!^jH9V*Mo>@g(T-1W_k6e4DM~aD{x>#pR~*Mw?OsU>zM19_Urv^IOm7x zE)r?-_&iIn4>QwE9!}la<4YUCEd>}GS zK})|&`URS2zfKEKhpA7+q1mAu(vEs4$zN@R*U*I~ntsEeYgZI}exGUR3iH1nB-cKj zCTYN2l0-s9ehT>zL^Sdrm9wzro~H9pON>7im3Y0EH`&r~)Dh3{8nnCEDePz;y*zjx zXyas)T~FL}_}M%VBMPnYqjNqI_zSf&r$ckE(+tm2&9nnLI|hq(+*RnJiGV`1096ZC zCB*LRu>-&6fbJ*f6qx3#l`UmQ6J6xvvRjEK>1QfDiaXnmMpRD0Or(&f(o-S?CLJd7 zg#@J6*^n{v5ti1{ok~a2Ob7%!Zg-ERVQu!oqIX;JT?KzBBn#;JDPBlBhO*B6MbTB1 z?A(Yi%zNCD2v&)wP5@cFk^hzD&KuZ8#9rVv4Ta;SfVNqy7Jo9#;n($bX@^sdDXyPm zadHk8zf!Ggi$UK<+D(A~P04D>^Vr8=Zh;EUY~3y*r`bi#JXz!?izBa&Ua)OtV}nHR zC=-L4rSXS~FQ+*(9fh6W0J}h#bNUZHJ*Ko%gCH|zpku}g45qRFs zl5fo(Fg_rAz3gf!I(!q2kXs%0S8YIY_d%X2n+Pyc z4ygiA31xD1@*gws=?E&eipKRbDS;Wx^&~dSa;Z5>bw#Gd{KE;Y?8--2fJ2q$eYnG# z3-PE3`=u518oNU#$=FsUsYEx2SQ(QA*zYRczqdQtdg|Fl&ke1fW6v1d^Q*(`&(Lty zM6R#450ymyYHys;JOW>R$S}0rL$iq*!=v-gMrS)rPZ-s_li6E6>MlmW$Mpf&EjOX! z3e@+jz_nov1ACzZi;l`OEq&VxNIyK%8sPgo2mu&9?4a3u5pyinw}tGaTi&Biwg`Grxf22vwC0znk>(U zP@6*7qLL0~eE%K(;M&D+Uc>~1h4)scj zHs9C;Xo{0bP0x@nsMQNxL|4V@Y6UoF1QbzL?0+l>w(w39NO@ya(Jk1QoS$=2%Wh87 z5Tc|DuZ*Sl%som+o*|!QhA${+h;ct6)Sgtczl#IYSY8qiC7ShJ95|}r5C6w_`XI|6 zf;rzPxZ_*C_CHs=|4FvZ^NzYo*5(y)_2U8CVgJqJOrXfKdk|iu*b?ibL;HW2=DV0orQseNR-u=rr zY4n1<)<&AK4 z@$}t;T{2fhC)_gkR;6dKHHALRR8OXhgj8xeO9DF|%dm5`W9|>4b4(M%o>9qfBj&)W ztR!gM6R);}ygGRqfzUkjWf#;yOg#6V+Gq&7wJkUqfk1)DWy3$>aBxvF9o+Fao(9B= zIcI=BJ`~qp1=#>~rUS24|C-c}zP}ZwTrl83G2EGS!kUXw>E{k&sSeXvRjkH$%)l8& z{|{sDz+HL2eS20#72CFL+t!Y4+pO5OZQHhOJE_=7MK|Z1|LxJE`#z_8jQtXR-?it$ z{7i6HjO0C@DLe9RsKR3V;C;7+)^N&2VFiB;l%vwnT<|w^!R^XD#>UIUp!b9XM}6&S z4B4R;lScEAM8-u)nmP_n?%2-!`^cPPF@W+u!QSRU&S*QHG^iZ?p#Q8VbBff($!oqp zFtl?<`_{R=G-vcBIs0gB4SXA!WvaPsMo2+uLGoU!aD?_@1cU4Hbo$vUa?ES}AwTub zcAQ#{eVAsQBD0cFqja!lVp;Qx3N5p>`uN(V@?1Ep{$FsRGw5dznQ`7Y{OlS+G>HfD z=rCbiI{JEq&&$Y6WKmfL@+t;MonIUu#Oe=Ly776W-GCfqz985G#rpFya#%kz zb?IJcfB?PeERFz?2RbYmAVc4MvyPc5ZalqsNL#f}J(#Ec*n?sNF(Uq91DB(va3A|` zzWBcSK7y+=%|HmYCYkh|@Q|awQIuQuUKoy)cptv=FUj%J5_R(_iRbm@#>+{hSYLWo zmDR%Vd-U}HS#dXtAndYn4FZpenMy|d_AmcFG*Vt8tbXwbGUfu8Ck z`GrsGCNA3!Bz!%T<66^7$h4|MEAps)EMD3{l%gVTG6EO_hQVC@bnL++p3HJu{JxiabQI*67fUb&RI)~=sRxodzOD$OO;fn!fZPybPH;Sc-Tqk^x_fGE!TVa%Feg*{_ zV;9IBFs5Jc%?|Pmk}c0FFV%;GeDKwUKb0?hwtAyzTe=LX=$%7)D6JqE z2QXWUzq%!Tvwh_{sL<5}0h*=mpw6!J{dQP%ka1%q+)K@Mr*OO-ytB*SyBjPVl1Gw? zTE%_WJRT>Uz5OToJPcb1Nb8{R4Jiw$WQB8JE&bLox~hFD+nVcOiQ9EV%Fz`|su$4^ z2b?0dTaS?XGZ||M>(v}D&#ky?hDEBD+kt3Bh8nuAfR^xCgtm~Qu;jnu)@Cq#9Rvw2 zqCGUFrf*mpY*zPPdemL0N znCj~Lhf%Cy{m23cM>EmjTr_)-8bSe?H}c0N!xtRyoj&{hzYvT*h_3dK&$q;%0Shm` zXL$wDB4(B9u(vAHbpjY3>I;~8gLsz%Oi3)a38NqKkoiXFLWzI}D|GWSe0B(eKOuWa zr>o~CNqvIVQbl|6oJHu(vP_x((zy4JZp1i}AH3MY9`SBJIFFS~?5mJ=!qNNfERa*b z-`$QDe6&XMrW@?8NVKMj|4qTd zVnHO8kY}m-%kD7r><%14{}rCD)x|?({JXt8AF!!09e0dsF!VfU2UYX7MD~66Lih-s zAeuk##DZc6gY#UirC&e#6iC!c1_;0Heoy}V_gsujXOyquyMaZ3|8I)m8(RARhTQ$T z2ePu#H?aDD%*LXWtmPKuk$q?<6-|=V_3lB9DEnD;%E2k4T@jIp1dtmBy*r#%s^r(_ z&|omX;_#RmH1oswdhv|8Te3hV1TR9i7f!NI+^^bB9#*ce`F>6sX6bJ}{t;bx3}`2N zC)%LbmP60jY<|tA(FyM7@}Z4>>qWoYVq|OerL0KNXCKSjI=N;Ks5jzJsTG6>q6tH1 zb^SAJv#T!KrBz9P*uJ}DQI{{^mo5tV0bQ1>{|b$y`Q>=ZC`4z?cxoDivDh1B7@Q|q zrzuJsW*wNUjiiHD9qT~AyQYW98H`>p@f>5+#a%`yRdjEn#Lg0&W>b{o$H{68qiQcR zuDfCfk@7YdfDjzlfBc%55ziw^G5B zpI}K#1^^B0I_bQS+J@uIumoKzVR9s*GfJopI8pNz=>NbNV=D!Qxng78N)NTUPYZra zP4M>NXCsXkw0R5Dcdu)qo6Oa!WTX~G(qj#D$M0;ZPk*jG*;b70WcC=AG|NJ_^0Ov6FMFAyGH!AZ?-AY&dlNh3$>P>E}#NnQSZZ z&`Pn4GXmqL*9MCcyX`DAgDgj*i7&?%>+f}_`SSyymTwl-?P&&(QYur%I;%l`)=S$y z17D$Vgr`C_KH%00L_I5YpcfAsv%D-#OB^uMe*gI)gEin$9fVb6i(W*+v?i$2g9D62 zgZx;=o?XO#AI7TL`g}B~6Bg(Y*Mu73QkiC@GGbS4Sem?^IupslOZM`rSQOsBF;@k4jDf?Bos5*sV&k@qDXV*tO!uMdG0&;k#lq>&!`))YXL0j_?KMbj zsznIL#e~MWrls$BJm1&rtLl#tJF(muiep63lEdS0(X-^FQFaj`hCh|ne_WEK`WUqi z>UF3wMCbzfN9uhv<<#19ZLVN+1Fs=`_lP1JQWA`3fPN62+=R^oXvA-83K1j4?Gg#j&r5*1elf zvsb}q=49dEVCBrnOz&ji&6L(o!!WEqw{)x^@P;-VjB!Lq5oZm3fH|ham^@yii68T` zNQeZTjj~5o?5mwfwyf`ubP|}U^%02=OK{ibyFZud%A+(sPdsg$jE3sMEd4#>T<+;N zZ3fJ#j{oRNWV|pw4w(h3C+gxR&oc)u*D|jxk{OhbY;q#f3JPg zqV)D?CHhc?i1$+K0kY~c9pYrNF;wDNYK#V+)|J2WJc=(jh_wkbs!Fm?JOl|GVayd%?u)G zNm3qpF0fX}kOLb`15YffQ5+3Mk_mE9!?o62(iQ+*ajqkSVRSYcU@>-6=FfKK+n52h zOD~H@fl>XLFVO602NW$$gBf_Q{6(AF9&9E4RCsN22eeAcJeW(ZS8S)nABc;UK<|OG z&saZjo!c7nZl8jO_dE`GU?K@j&8FNir#gRW81l#=gg^3%xZVG}L4uq z?&Zk+fog&~7=YarL+@eU#wzRCJ2 zY-LK}v`_5LB{JZn$T*r4MsPK45Q*fFUT}vg3jRtUFrvRl$SZ`XOBhsRFM;41r!0-M zM|j;Oj9wB#Jl0Sfp+a#bz5rJBY|b)9-(jbUuqoVQEK&=W;t*AD<8yJTL28Qp$o~Lp za-2he)2`UpSy=*E9mHF9HL&TrS;1d}e=nq6B;BJ-F&D)+(O+7OxHDHG{UJ~NNu$x& z^nzy=1E`%8rtu9(K5lxsHftxw!QFk{&FhS(b%*401F3mJ*SN?0SsvLkaA1w*OEB1C z%|)h+?+K`yY}iJ9nYHwKcV3<+Y-kMRHG(&#&tPG16j+8=5hwD@hzD%5#8KAriJ+xq z{J~+xsJU|rxK8qJlMANoi5~5u>&Cn|J)54eJ1Vh3{nfGZhf_c89MX>(MMM>)7*&J| zYfE47h`6=tLgVw_JS=ornVhWe6W>h8|0Zt!j{v8Ci5puR8{>aZI7IagoopTc$6FT# zuvS7+{Z=>B)M0h_;o<(3wk-IFy0hh_D2AbnvG@YidPNfs5-O}6`mVt9vZjC8*7;^@ zlBP?QN-o(<*LN1r9@a?w`}3!#H@luU?>{pgulT+`KFNLyc#+wy+e?*|AH0&NdQ7N{ z+i9gqay8Sy>^NO~huYw{$^^lid6w6lQb@H(mG!?XZC98fv$qDg>fL&NTlUd%_ zLJMLN->?xRgm-nTRVitBiqkW!E!ojc(UrF?9sy@DuRXz?AR2XSRz;KuQyl^4kY*ZO z2__0?gmAJ+z?)faVv4$yK6nw!Lz?Oh1BpAaRY*gDT6vX53kHK+m$b;JCw$#%iH#2T@*_P%i(}2pyCL8kt2BV`Khl zUj|ARny6KMhDvZIe%!3uFOP2zSppn31NygsvDLwx%&H)%yoeA(%=U--+Z#Ao3Ph%e zB{s|{8apoN@ypv89(*fLB}N8kYn3`w`sK@d=OX1_|3wR2q2>4bMJ-Wc9$i{9z{)Mo zKwabY%oqKv|2_3Nx#5}w3K}S;m+G#DgK4rU5h7C15I*gQJ%lPqyK6+*>3O%ZJs_7# zd-R0qOhRRRbKw0ZOUuNjo?ev<@11tF7HKVc(;dMWL)d$4j=?%2w79V!mYUVwpm(bw_Q+;!`f88Aik&B{ z*5`TTg2pE8^KBBR{EUn$X#2tsD9ortm!oD_PC|VoPcD9hVXBPe zKCP|FnZ#yxrR?J!wdnK)dIU$l5cM&n`eJ~?rn~>7ySNgXG^;q!bE-J!P409C(gjBA zfFq1Xd%xD^@1r#YI^8O;If%0fxrI|GRWci_-@YLpjk;YpfPH9(hJn8sg^zW-M|-88 zxK|lp9$PPm(6=zKMH+Oj+NulpDwd7;dd>Yt8rk*&wLZLjYlqWtxkGPoz#)Q6xgFre z1B(Ll3^+v6NB#+^$3~e-x?os8MPJw8Rh$#JZHX*-qxri~WWB6}XO$*j_-LkoF*HCQ zJvaW2G_^#qFjUQR0BW^n_cJ(TM(C!6{&KG!b$|1L?_ZjFIdmED^SiRb|JTY&_z#*| z#KzFp=-a&fpS@X;8kCnN0OwOSp0!22z5e3o#`;`c-@1wRvd!gs9n5<5R(;W#+Imto zf19Q4hLyQuyc0b<3I<^}Jg8Bwe`%*M4vr;Rf?s|vIexbQ0>VzXzdsPpxq^yqnb@{gm8Z2?d%iAq6oxiP)?l1JhhS&{^lf z*iLGsi6B8na&k2`%c-N{zxQ-prEf0jF1v)O*fm#bPk=6GIo4{EW?-Il%g>z-{s3D( zmY597jL|a>{9!@41#b=sHb5lA)kqu#zj4;hGUvwJCEKg6(k-)_SjOJUAg1S$vs@EB zI8Qo^pPVE|vk;*~zY>tZAeUQc^~dpOqcb(g01lfR!LI06!J>5^1FaRC&E!*WP!P98 z2NO49gtdflk!w2L*;4SrobYCp2v7uZ(V_#OY^;tsTRf#$G&lrltZ}(y*U4|qIHABW zRCB-2Akp0((F9q336jn$l|ogjYcxc&IvFA}lL(?|OJg$X$jL>DeiPdqEj5Em^@xG9 z3X=*_eu$7EAdV<+s}$u%SjnN}D%6}2Ude%a=Sl?U506^V5)f5-e0q8^Z>S|&ipH9b z$J*V56kT-jFDWt;i8EtB3Y8iW{eX*6;F8uM$49-;Grd2RB7E};Clmf z@$|;*nZU2<$Nm7IG|NS64Q7pQZk|9 zIvpFtTeBL>2%U0w1{{(3ifbe_2Y;cVsIEkI?s!%`x@|h9Q%bEVW|=d1A@r4dGZpn$ zBQm#J0WWcri4bEQDH4`790wyUHqU-(9Fuv_je3oz5fF=q{69F09(Pf~0Z|8MoKZqXruvjE!Qpk_96GI)+?byo%*+}Gqv~u1d)IS#C(|JeM0h77 zhd62Z}^%IWDNJqdG{^9_4ScSjX5#(uPpZUw!Zo*G@#cH%eRIs>}s??PMt=&yr zJ6n6hzVJ>pU-hOwR{zs1cu$k1NluCpZmM)NbtH;;VUb{hMmQ?q;d&GM1UetqKjZRM$r>5sG;yH%Xt2k7<-zu%S`S|Bxh?sLHM{`^{c+7SX2*arn+a~E- z(P`E4Leo&APE44T7#q{GlOOv+31yG{j-!jSWi*i)RG{vr9mgy=~g_3|^1z?rhwP}g`YQ4icOg{=Q zJ*+oZ(*;X~!@^{v${+8Pajn8%uB(&yHZ3*BqgFCjj~eq7ol9lwrM0hTG%K7pacTgx zg<`UXFi(wilviRk14MS)DTH!QO(J?(_)NbOVlB8ACFA5%e$?L6uI+4S9-YYZCo~qyw*Cs)I<{6NTuh&^TV8^*Jfr7y zzz~Q$sKpVnEomg^(p_Uf$VIVm0zzzbslV3{hSk7!C^5vPUF|MCn4jf0(B<-H8 zl@b)%*!l#UE4Q`1q|-g+j=KnYFq)$W7v>18HJMS8RG*+NVeENll@qSQh(+VOG^Ch| z^$9lop?+iCAEw}`-XAuoeLbf3cufk13RL5eABNE9=xeKtIpE)}&Mx<-y2SaKg6+A0mP%ii+^ z_YbIT9&s6BAHe}$;QDnHyx@}xz$5cbpiQrY!s?!?raa-RX-oL#k0^Nqi$~E}#cyR1 z4t6l?I)$RLY}hyTFbHxj0RmmWea7)}X#=?H5^B1&$wi@!(fiXv?>lV4qtKU|Xjzz< znv$u`VDf4T`LNqbhKfm|xM`}MlwUqVYTdD`kUr`{yl9s=W*B5m*gd7Ef%F^G-huw& zj#jkdB|V#{9i8tcsoP93ts(0{O*7EJDPl-yUPLHI=2_xx7MyO+us>c1&FQnZw_X^J zKE()b*QFo&x^?w&OCgh(>+>=T{dFw#+F5(-HdiUw^a|{#mywB zin0qy%`i|uUYY8zpe4b>H_O2w(mgcj#XKm`+49V9XV$0z?t3EVb zYS^x$DzV=od#xYb61u;lJs1V-J~BAshQmwed6*FF8CLsC1o{N$ zFmo>bYsa}C(&ttf#Vf#SyU^cOp|7QESMw{ypKVV^sjsPC+1Nw*CF_&O@Z~NL8-Ag| z01%6ytOw2+erAnP!R4+>Ib8ndG(MP-ZrFZDczH;j)u_bJSV&~ zFwh!(=x2g?z*wT;pP?e47b@RE8Y6jLPBEr6Te?^b`hL?SXqEwYCG6mo-U7_|@0``c;QG7p|m!udAQ*X?X)POcM1<7>BV$ou3zmZouT zO7wo1y%*m_jZs1KNTeJtigx6-3v#Hf-TdA`Lua z$^MO|ExC5Ze(dJ6oBb+M>SsWT7I!lR+fKv!teE(%JB{zl7N^QI$|rO92z^%^_D&Yi zX^rpIp*btPS4*D~b)=bUV2BHKzrN}O#WgnUg~~cHe5|%g!OA+*f4rtv7lg903IwI8 zXIO;lk{(6VTsy?-BAOkRG?%lvo*3?xP_JA<9pQ8|g*;*H@r?@5D5+_rXj-1)%&OPu zX&WxCX?S4Y7{;Wr>WXSoTNTCHFp_{d>l|P;j&Syy?l+ zaotnsz!AIr8@>Lh*)h;sZm9*0-JA4m4Ef>G&25a78Vp*Qr1trjstcsBeT9StFwr@>2LKgAyp4OZAS7J*CTXrJ0+$qWC7miQM$z z?ZzNpTMnoU~m3aIs6dS$(zlIKDHu;NW93Kjto}u{w@!#Ob;B zDs1R~eWO!H-#+PN7C{nL<5a){SR~?<*ou*5LTC~_94E#I;^`mc7^IuQ$M-aV!|(xb z_2rBP^haD#==+)C29gED#^E@+jDH5GB7GjdpV<;N6)_~=bMw$8Njx8ZcPT^px6+#0 z++Hc?HiDTUxx{2+$_YWxJOUTb9edIS*{2HXj5rAu+1gcRpgP%easQYEaa* z&~vt<7x(?g$cpU`+}yER+=@6~cruSdVF&bAfy%%yX|P-R#DWz`=mGwb@@*w8QiK(K z>IOaNA)e3ZH-r?TuO&S>5Y7l>p~uDj^fW`W%rKG&=z)G+W$0I&YWGDXvGlyn525xd z6l-1sw^f$ezH0ENpmhZ=>g^GWFV%sR1oC)7iT44Bn0K1;7ktFVl;yxQdgbkDp{X>7 zeldUKP^2{GOn2;Yc|QGBtL*J`V5j0dl^lX4t4AJW1=?PbAtBr#ZtQO-_g>~0tvfs4 z`4Ttvw1+CXRu@)$_1l)Ok4U?b->;wQO4m-D&~)ivesk%T*^a_)6Sky^A%=5s39;DM z-t6#lMUhR~#A8>Y+{CVE9eK!_3Ag;E+3pzkt6v{oZX zD4{3%#C8Fhc4w9@3XIKud#C`8TF6>{^))rOa!p2;b#W6#Cp+n<6!PujKdA=k`$tb` zT4p;L`Rh7q24!8GMJiKS`+vwfl-QU?XWIndD+YT+TX`u@bAz3kFLX`fY9lRwPnl54 zm?UzrGFd3HGI?lKG=rBwQnid*kssS-T}@Pq=Hv@VwD1|89oTYUY*?vT*s}i4NM7&5 z;e=@lpjM9?(B6>w4->3k9YmGr`x}J&uY1;inzsM%nb7}Ll>SqPvQ#YXltxfKmpwKu z)$fGxYyI6>V$pxa*7Zq%$XH?tfz(4M1F_inS)Q$fA5sx%BT4_=M=--&kBz+phmc?2 zpXDbY29{2EAzL_eB7HxvaVd6Ai~l^!nJj#aZQa?Xx;JA^9LBxO=6Sp1*vaNGz5e`+ z*opq37WoWvY~tvh=V!HjF>&^KnI_Meu^?nE%9tUErl}w1ZB)z zK({#80FXL&*bw|3)OacV2lxp>8l}`79tKpvFFbL(V(u+aQBUPE zV2$q40Mmlo4P>F~re8H2aT1yQ%tnD;(@!o}nT{W$Ut(*nqYahKvDuF!RTC04h9Xr; zJjaH1MY>9C;@s7odC|vx?~9lf&N+S+>DjooORW!x@w_NUT5yK~sSLdi{tro=2)BYI z689X%P^eRj+g#|-{96257R-@Mmu_EzQ}L0*x;!HnJ+ZuN4MN9ZvS@fIAtPLl=xRVo zZ@{BEsYXL^SrLqA!{j(E)c~v8tuyz5{!I_T?p(YC>2T)XzaD<3mOX+DlT;qEQ)ajH z*i}GFL7lWf>5;4$At>^pY+#;J8nXATmCHoosS6B>86*@HGnQ(U%nyFlHHz{zwYDY;UcgqU=*dzuUOA@h`yrZsz)Oo^`;Aw8acdOCJiL_&aNY@ai=+0&!) zHP820XyYcEsO&EI(Ihqpw48N93VqdQ358VJZwFLND`f)toO?2C$p*W{?r>0rMFucx zi`vW$zl6T}D=rNx!I547ff4|{@h5szi833_jLtz#B>pUq|0xc3EOSF7y9Kt>_kJmc z*Zt$ADgq7QmC~`@WUNG$=9QCS=~=xL?<=lCrKwV}Dx^Xamn5ZpVR%$|Y)Y7YdZ9Ll z9pzlMIx_`rr2HOAb!1AkoV!1gSXCpD5gw2!mqF>n$(*sSPKZteWdW6Mgn!Z-2%?8L8Y;=h$=<8Nzy~11Q~^ z_##4_Z#`$ZD|wdg*c~*4&378Je~#Z7lN05?5GElXhL*l<5)@ z3p0LO*2qe860(^cECy(vmGrqg_q2j+Hy8SpMb$zkPLq2|hdUZVwSjkPc?ZQ~wxmn< zXu%6mPt`4ea+g#d2-<2pjq#5j{qv@uH-?CBirdsb^IKQvgs`0r_E;uEwTCNfnNG3I z9XQfAf4cTMi%P?A0$&B!A}Vi>9O$!@Ml&aIrgQ(4%YA_6g(?3jC)7%<<^pp+u$}AL zr`{TJD+XcH8vT^J5?`H5p@mD0XK(!}5A){FD`w1%V8pjC&4JkGAU1n)c)>!A6^u!X zH$2yF&LWIp2eacPq~XO-sx@$TF3z6rm29?VS#HM+0HXv(F`Y%HhErw@tT?TcY`>R6 z@)4V*lff1%YZzmLPIn3Vc%vM;dBFqXow#|=O&O(9qi}!C>GC%lqbSRH|H-X=c-rO9 zqKeRi{B(J5r@qG9g8sRm+&V}ku7?Mki@9=(_MY`&+D~PYtDzivRv!Y4hH<`=XMqin zNA{8d2aO?jOPmpoEC4fpK0^*GOLELHZ1)dZyjGO=#**zHE=*nw{$} z7yO4I)VGfX?1;5kk!3pZmZ$f}s_GY(L8klNj+6Pwco|XZL~~k)ZJ%_b0Y-9z^+Adm zXujG|YU6jJig*FAdS#z%rEwx+q!O8qAoj01Sh8ANvRmuSAy+$CER3G17j(?eNL*3I zu%5h_+r?XmlTQh$90M%gfgk2pXgWGcD4isxdLgMpH7AB<2=}-CNe3fp@ENZ^By07? z+ibwH3l0l(e|1%tT;bpEEPGGBf1#4_b@7GMF5ZVu$325N-DeG1ko0)$Yuu96Z;t*| z7uCrqr8-EE&clmhqo@eZGzCsh6qZ!MAjv|MQdzv^X^GpWL&z1B1}m1o8$AiqZr_Ya zVCo&lT*lOjzE{~=$`qKiC|Q(&YGq@i1!u>S%Tqqye&NfMk>rm%#k6G1RlBd}k_in*O| zLKb+0Ds0ZQVmIe+Nh|{KLV32S1}UgdC`s9~Jp0qQNRt;`rpm8d3<*nau%Fi!LOaV! z{V6%j7denjYY_f;6cnZF!=ZmR9#3i8S}xC0#zAC5F0iw8%DtXklXU|_M&)phXSUV3MSaY zdj=X}qIljnF^D~mE*ZreB4YzruHA1(uH92RU+>?G|BsjWys1&s0w~eG$>XH{d{h}M zcM{HgN{wN-;aPSv-Nb_QO4EX{#msotj~jZBAVInmhDFkl8Ddj0#00|+2{6?ASWEgv zn8D#UGE=Lcrtw@k#i#1`KmjB2Ob?S750x@l8Vn^PM~V3if%_E%C6k@yrZKTw?nF5W zGQqzoN|;IdqOiyK5_PZ&8o0);%&9Mus1a3kd4V#>^nBKsQ> z93t+Zyac#sA1J>08*Wgiw!%DM;);MKX(r?e4_NKrWuYqt4R$e=sc6X0?Bpz(ncY90 zcW6oL@bqiPZJy@xzsXk;Bzk8dUL(;*!en0}$y>^ACt1{7w1J2(LQ9gjRPZEOR9}oh zOsD?yJ1|zHYq0jxH)MBY0(y#;Lz4m*VxK;`+Aojf`JgorW_1)eE7!yng$V%*v1tgs zee+}-IC~{hYMGlX+?`j-hI3e7O>R(+1d%PcW3yIG$ip6MI1{%nPhCl^s7s$=M+1>; z;y28kd4HICHKR(fwQ1{l+HXzG(#CZRA26b9xnAZO~K(uDkNc;tVLuk z+%NubUW2~CTv_mzO@YQpy*Eyr9T?N*mO2>74QEwI_K)qtQycMO($`zm5TVJUTSU@0 zNI}tb{fG=vWBH(8JToZ2zBF%vRFx@es(&22hbl~u&V?7i%4LP$PtfEI2|fVTH5fOu z+=eM+Ojpm#Sok3^w11UXmZ>I2{vc(^>lXK(gc}DP8cqeh$S<>)YmG~08H#Cv;7te< zuJ44TDongb=~N1sa7*FW!z@wVgn+MHaIroBXhG$}T_a&f7dIu57+==GHqGW?nT!|@ zUCcsr6c_=$gjz1(RAMnd_*0x8H&&uh>@JVx+mv${YtWQ}7~5>uB-Bmb%AAjLnHh;! z5mf&fcVkFVykk8SBJ42dsJUyHs?1FxjdV@fy+7D7cg(hS9ZOTfBjm#iIzqqk zgBi*ug2ozUIpg&XB!!{d;>Bn3 zY!Ges!2LUxr1Gy#7)f>le`mGu zBR!Vyp9}p}>z2dhONoC97pD5~bZAMS-5~)X$%Ama)M=Czg}$7TCBz%y)HdRiSbBvN zJG%K(l3nO2SE+C00Mph4y9=6*iXfldM8M1$hR6~Ubg$gck5j|vUbLy&G|SP?g!RT3>HYfbPlgTSlNdM*t#WMK zIU_&X4^=QOpdIdd#u+ZJxRqELeannP(~2^z9@a0pB~d+41usgzwVyw>eim7Wke4mh zA<3}p7m6qX;AY8fD&w+WrH=}j60T??VK}nz9x`{IS#ZnBYr^^YnBLpAp>ISO6*P&X z?>#QI2Rm(~6xI{y#)Z`6%)?uXFns=O@ctn9K6AN8A4@aNgzah$bi~H@ zCJl!Ovvkg=?9Ow3pz#j0Rb@6W-qat!A&Z!9_7byx{iLuqud|PL#d*wkT;ywwZvRbW zbAM(}dWW>O=`BfEWw1h@TJ73A0+ErUjYP4ZZ_RB5*Aj=dK=_H^Lsz9T({(3Zt^n}$ z2eiHy^&11Y@YX=KF%v|7|^gWl+`0ZP>J9%OtX zyVGVzCR#ti<9>YuOL!4Hwh^Z*zW#l-*1snuZUy$^N9=$7 z-z&u}P0~08T6ttCB;aX_k1~mkNd5D7A!SI`+2z^Q^Iw_k?!Rv}Xg^rxQAgW#h<04K zd|V*v!;)II-aE(y{9bwrx0Eq} zL`ObFAVcGOOKsg@&Y*-R&;T3A;5Z)5*HR&Mu2v&Y*O1?^Bid-$YX}gfGae+QROo@; z#4v@xVT9huFosAfDnX!6zbyncs;`)231eXe0(&BWqIg3MN1_WZHo$nJMVl-T)NhPz zzTsT1C0*uOepynLraU&H+OsJ0=Wk89pQ9 z_sV8=5l=8wy;Uhe7YH|?Hj>Ei5wYL0?lbS2(Eec*K}hleJh4ZZkkwqd?yR{SZ}<|r zs?tG|h1n#Nv{TcS#(RRD@`6zppH$L)5xE!Ln|l2O%#mDn ze>T|>L8rW(0_6DZ-)2&RHbi(1kN6fpgueR!!P)QQ8MCx4r3rBFsNdP!X0Pd;X1ya76@v zXy~wYyute+aJ7)8#9N1?HGU{d?^%h|J%3idX$1?DcPF~}usTH_q!cFI`V8JaO)Vfu zHQ(A!chPMExRdWx$rgK@BwhwA?m|+Dq(-M&>9tKl72=6mxk(=y*!TWhC1(! z99x9q6~fb#)mLO?_V}B=O?$sV`OUF(rj%EGLEMDT;y1FqZ-Bs8j5=WNkdf!muxIZt z2I})n?ew;-2&>17FyKm`>5k(Pw^`Qy>nNi*0A3x2wTR9=D{6;uFRF!>kj;uN*2I z*6W0pJSs9ImHA1^l3=8l3jldR_en_`4zW zM?+B-R+XgRe(T>1)9P}?(??+-)ZA$F!>_+4*p9}iA26|$a}@j;S1fBSO0~R8K5m>I zozReF1>kms_*H7m8h04YUk_K(ob*tSdtPOwvPhcfq$#l&a|#?fKj=QoxY{}XSO@kJ zBfAELzc?I_spCJ1G6NdG7V&Ppk8z9KrO@ytauP=v(9}53;&O-_uH2f!D{*}(Lw_0^ zKYfRRn|W3~>L~z}8|~q?XL@4NXmAJt>HLk4UbS1n@QC>YMia-S)88IDBPIAiw+nJ= z>-Qc(@1$&tVho`rHq{!-Q)BlCe_;b35y!?gj2!4xvr}0<-Oa!@=Lx(fN%%`=4xw7^hME4zsky2XR9jRE7F(zpG*8KhAdfy^&a`@7MMB`zZ0B zU)MhkpCye942ATqtp4rpk+3nb{hv1`FC#U;kDPf~5;a#?r&7g3PS}hxIh3(qBrhKh zndIMPy})7<7DiguGaleCa=j;_WJnwa~B>EyoK*{`Gz09 zB`*w@eF>6RI|JrjGRAWq9}>s@XzS079>8%Jv-#9|y^i*gXSdHi4}FAj=eN&LI2PS! z@m0=gPwxF3Dv+RHdB{}N86!dse_aG6q8YHK2E6nH!?I1 z6gj!F(db|cqrs}>*SSn0(Mfn~fnu`7qdSK=MbHFufS(@y`aIf6K}R=ujoS{=A8WsX zE?T&vKP5s{NRfhKjfG^jGHr|x3lwUU^aN5vMd@G+b>b(S&MSlBN-UVRYBm=!`mE)K zYII@WuuBT80NI2?5$c6P!Gx+XXe#ob5Q>&+{)_p@dw|3eORMrfv>R?gukVK0Qo%`s z@;UIu!I9F-$DvgveEV5#`%{5QA7KAlWJP!`fLVSovTXnBBI}On~x5a=(mv$BIpLpLKe;fEffZxq&j=bBg+qKH%dYH@dZ z`}I%<=WT}PHYS~kH!QJmT$V8HRLqohmVozn)|Y5u{o_iT;NUyJIk=1OY4bYs-uonb zNjK+n59^2NODuGG+E&I`CpnQuBAEf;%{drP)&1sn_ zqQbSx-?DdR%iF|oUJ#!?Uu8?EKKLiedX}mJsQEUmI9zlU` z0Rd8KHtawHnI`>O*_)sjs}_S7CI`WTh03%HsEzM>6yk43fI%u$<#&`~MZ&W3w7?si z9MP?eEom69m#>G!Qn9WwQK^KhXo~8Jid-O1!Ku)hv0|BYARS3+(`Y_CD?DlCgN6Y{ z2%IChXaDr?*FgmXg9!wQ#>oux+XE-W#iJhH74v{Do z?`kx;cU;LvH&XfYuQ@Dl#Y+-k^`SHBL+_1%K}&KX4Pq5u7tMlALq3o;w5+#=>LDZH zppS5fQd7~6I0DTXHCNrbOH1AsgGBp$U0My$qE)5;L`@w&2)}LVPwf*q*0-_IsCUsN z?`n%zpU~8VnV?WhSYyS_NOj^4kwW}a-&@975OC_meLUj1Og&jl|k$ z`Izt8Y__g>OI>pqXM58y5yf-=*C@qo9Z7_1H-#Sm&zo8mUF%ASL0E8(A3~^e_0X2T z^PqqAop0>OCVaSe(_Q)wGo#lvO_A=#@op$KO?B;X`Tl5p;C8J&0i3nsZ=YdH(9J0 zA;s~uk9SsQuxM6iWMo~`21S87Hnickj)Px@J8xBQ%>Vf;cAm2@w;IragFC5+(&%e9 zNTGpN)Q`$3__42OH@#oq=Wvk>BN-KUoUSbrb-{!k0H67M;~rB1dV1q{Azs8cfMET= z5bZNw1c!G=K}ThmX$Z8DNy4r44$ik|O)eaVmI9hgw&C)OBh9uu1!{n0ve0`fj%hu;1($BzJ*EYMH2FXWo>D`#%s zv&PH9T~NeZdX7QZLpJue{_qPW*bSzuEa6y>^&^UEToWUPxiMqD*?n0W@nnq&BNq(c z|03+2f-H;Ht--9cZQHhO+o-f{+qP}ns?mEIrCmltYQRZ0xkWwyBuvl`)7;4MI^DcAt-m3JIIOiJEi9fqqe_1Q{?4T1 z2+u3Xd_da1+w1ZTnKP7}d>C@Vi8j+QOx3%YzWbB9a58U$D^EGn_|B9NYtw8AynjoBcpEa040_9TK{TP(MI*MR#Ft`b`t+ z`8k|488H;j1eVm(2W$~VZ^^LB0p*oj+K7pAUJngf9@qWQQ&m_GmH8F%N6#X!^s$}4 z8EnbF@IyvL3eJ#Nu?kZk@K|_43rYYt|4HKALg|42p#cTk*DGMG87kDYZ>Z&~NWPZl zxefQPu{-OZZuEWf-i!!fJEHKF0cR*Pz);FIjn-X}unL!6-E5z*Y4k57XR3iba&*I} z>{8CGu3QZy+SF0Tp_y`xtN@XK!l)jO>?}S!fFoOEH@q(!ur`U?BM(n@&hc42*TsFf z<~@EgF$SLF_kFmfgP_~VzF6+Vdgrit{XzfEsT|PU5!+k3O+K;Wqiac!|vg(EUenNosx?onVhzV(`gwA3%(v z%Qtptit(B*y^k4I=Wy-&&^;O}baQa44XgnJs&Dzn^Zr}!Z}9AA=Yw`V{CK@D0l2EI ztVc#MBdi|cIT7E{igXdMA@L0OB8jrzn7TFJwIB@=ypkO>fp zx)s?6;Yd*T_782}Gc?&q3nsbYmeG<&wgzrS8=R7HtTgleHfla0)g(t^nWbGtOqovbKetVS>N zap)hZ^uu0j3Pa8Yl^7Hsy?&r?T)QX#6POt1mon?>O@pV5NW`35wQLA8#^~VEtgGX| zx_Z!4X^6OKWM>H^w$j1)7QoeO8rIE12-dAF z%mY)8XX%-o^Kxk#Q#;qtucL8XF%}hj+d6la#ESD@rZVe;KLyL()-&Y4s~f1@0l{0J z{QKvEdwYUcdAX(k=-9n5{PmZA%cG3nGWUNkaeoMf3oBhL87Uzzm<1`1JCq7W`3GoznJ5_Ay5cqAe}_qePdPvJ4K# zW2;9?@fe$63tvP`#B{X(B2(na|8-+M>{@WpFlHmr7 zg1N$}n8Z8T&AXJbOBSW(?U~VU;Keis8Lmqm&>iK6DLCko(JvO>N zkM-p4#;;T-?}sqQG-}yOc4_?*^!8XjYWXLcgN}hQ^t0M4)S@jczrGhlq1h>hx|Uzr zol%vD(o&546iFTe4jA2IF`VQSL4zpG^|n6W8?{C2vy0q{Ngr#VU^;}d-suFVkuP{$ zgy*e)3)jab1t@A1yTNAsJu&v zDiry})Gt_FdxX|Re>E>FbzUHe)s^LwD@ZXxZU-!juFW`P({$Ww5RN64@r<>6moQ->vG;JOB!=_n^$P!?1&hcy3 z$LA7`{pQv`DRd$&(@7lk*1m$Sr49$DB2I^J!_ zu1dMEjR>?QBYRlljg?W_go%bVJ9DOOr_DUFdwsfO$hIU~ljFjBf~0t-dj$1FJ6tNp z2xyvu6^>46M6;ac)lMs6IfX;*`@}%XXIJ)Iv{jK@Z8C(?C~je_q2FG`mNbnWs+E2}3$gn&=8N^^NxF7q5Q%V?VA>9S3A5`xg z7U|6)!Fpu*Tor9RpgeEHBcafO%`>o+Qw)Acu_H&IF5sKTH}K8kNu9ntl5LXmYy}5S zx-C_iBqeft_GkSB=j_+~ptusm&v&|0aGhb`o)HMj(K4j~&v*5I$Gl@GGigL0ki_VB zCw>deaGi3zlNAQDOQ!ai$~#_l8{|?YFY6RMYg<_G$DK=t1Jxnr9F2#|+Uh9h|Ijyy zJg!iY)wRAg+sZO5qMea|eWl)3GkqwEAkL}aNbrSP9>VQE37%X$2F;b+rak$0&i=6+ zc}|?G)Ia6!))f39`nA$WYWv`v5P=(L6fni;L6Z5zmCnv9-|fmU91}colz2B%jI5N9 zqb@OS6y;#r5dT3uUSGOY-S$o6(HrP58R(N#r_k(D9*|(kR9Pj)=Il_`5|n~9dULK# zbEs)yoM+jrl6L(~K9(cTBy4Mtq?zaVi5M3d-3 z?-JfG-USV>1?ZL7H{Lx${QaY`pS;^D-UaDZJQ%%88lKr#Nump+OLeE!ha0Z-Pd8kv zk2ied-vzM^*awL&+%~>Fz$Sq`Ja$4GQkTL$Jv*U2@+OHr+bd{JbKxQXv% zZ)w9_17E~HWp8!EcR;qu?mGKcBtLO)JxP4U0@_`rH}_Gbz$8NRb&#{k7K z`JsKQuk||~z;pXi_g6@R7SwTkvfm(_{I2_V5WOgT>g(L_Sefr+V&?nK4<4J5oNB{y ziwylmOv{dmVP0St?jk-MoH{tgb}C+BK{-6g>rQd085%u4*Tb_*Ng#2MM5%H&0vjwt%t!cb-aYK|yUR!*DVI9?QLt|zXw>aL%d^8VOPfpQB&e&S# z?h7A_I(OFyt~E%|u#5RlPR)fr;n&cPPS*y&#`bt+={DWi?GmP+RX;Zz_%uAGu1D=X zj>vVeO-jK2wt=YiWaH8RGXz(im=_C%PRDN@D&eEewatA%G^_Y$REWq-iP2OGe=!&M zEEkw)%41!X!SH>X;)XY*XirX36Yf#&d#8o9GaM&08ksJ~I}WUbV}uGfeGyZg(cqz* zOnaW?G5a+1CmEt(ZI)(ERa%hXp}Tv6AMHbv9h>A3=+i=6ZnD$tZv}k zx_TRifCP#}n#VayKD@dSC-#WEVY1S`V z9g0dg5j|1BE$kU%z2jynNnC*+kQLfkRqs_W+cYmQEgPP}4_QnyHL#HGEDDA_F{qW% z7*mOyajxl9cbW%iCONt_{skX^CubuyNpM*0(L6xMtb;8WDxd#n!1%ppolEyyK?D8Q z0VDDM`WAkpTaERti5dPgU-V9}{oTO859j8u@=cOq^lPMHJoMHu(NT48z z@8GQz>o{ztbo1=5+y@if1>^mLGfwMvNH#l47@MBteaKuJ`+EO6AoEjm6IEB}xPeiz zde7v7njY9o)Hyi;$NSXeW+DRP$z!xHV)HetT$Dq(Y1W%UkwGIwC>P(}B z3{s??6hJP^iFyxOGBH&YAzj_NOtFVs2nxU$ZMzF7%~6kQUNt_-i7IlJb7M;9NpWdt z-SSacuMfIsE|DjpX8ozH_*()F)(AWTD^|9%R$D(Xz|nL4Ky*x|1o5^&9}X6z?bs-l zHlchq5LoMvj#*BKCPfV;h!V+&t3MZW8`SqvK?c4Q6E%2p_$hp9_(Oa+X(a~Yv-;HB zbSKlmK76-&ZSI#I7; zhZj_O+5EO`B3WI1Q`VfLr+dewRR0Io?`RcMqm?h|~lYy1gZM^doRoms2rzzEB&# z-JZ1}ZvJNZKYjSXFx=JnFE(`kYj^ekiw(yAVB=Rl^FIOXSyG#6z-XbfA&Qdbef)^L zQIu|!`~G2sMYDv(lDTx#d)h}i6K~pmv4WI{D2Q;M06xeD)~%H2$|zDjIJu^#rfUBY z(B$L|)L~!D?!+P?S;Tk6e&R3p`+iuMHSKzCXTS{4ZXSVc#V4`TG!Z&Y*DeS3OKFTRhFQ8eNlEYupLcV4O z6GfShnaYdYr|aI-3VjuSCInmu<*$sG%=aX5P_&(A2alk29O*+{fKY1|;+S%wsZ3Lz zmq$yb9^Sfv2LwyGMpuM~eagKn@#KJypoDF^A1spw7UL)Lv@3Rsb6{z&7WksMNVUm`FZzS_g`_Z4Z%f8|0{S1|9=ja|3D{O3&KnJsG091Gkua?x*rj6P~xxrtWg3yI65=FV7~!9 zgg7AP+<08OgeWPKy$Rv&ye7z%iB`2vQN&E~Q8(&`_TK=J;z&!i$}QcO=kDtk)z0?6 z58o%9t|r&gq{>rr_gf#;C!aIlTd&Q&-gowdniVxh6%k~hn4t$_i~RlKx(L>nkz`TB zG8dgn5Jb#}q$U|2?x*AOhRn!VW}9sX4uy0_q+kooTUg<2Eg}aJL`_5%ZDYn4x@b5O zuo+u6CG)?QX2x0O(_^yPy{j_YzHFsqGQ1^BP{&b4gmc5oJQM?2&iaH2jEE18I6V1- zet$s6(~f(Si)}I>0U%eHSWpVBt*hv8V+KK4NuunE=uqS)^$hbyR;`G|3fP;n%=@%7 zPf8$3bG;ehrH4OUFw30@((6LY8-(IEx6qjsqqm;(kEC-1vSxX#9{&u+7+B?){_>Z& z5T$6Wan4K?H#DbKNWadnB1a73T!?W4)t}5;28@nw`8}=NfSYJ2xrG~>SrVf7zgMev z08BkM^B^H60;Aa&dD5sMm2Ni+01r7g?$N`jV>d|TueAI4TrL5>gVJ9O$h{|5t+N~7$K{1*tP;IF2!%jPto|kC zi&w2iv4}DQzqaFWqo?df{L3O!hgV2Rw>(ElqMT@63*=A=5$u$)H&w3@U)2?X+Sn(m zPhw%}spN7TLLh7nCb ziqEZYJ}U4Qt=KrVj2uzqk16jEtqnsj{~n(3w>@~jwz0Hxzfv_b{Wc>zM8u?LCD|Xa z;S4P|5+O#Fs5Wv~YSPp0ToOB(r=+VcT9Ss^$)Rj7k2crs!;H-9GPm?*j+I4eSrKa0 zA4DS+92f`~tIAlfqP~1H zy_*KHyEerd%N279csYYV?}6z~FMxu;K{8lNFj%gd4?YWGL(U-Sj>(L^@e4|zW;{m%&&xHZH_r%p(uVdD`{v=UAMo zQ)^0Gg_P;Va&Hvb0+{rZh zh(bBI{1Ig}_lYw{Y@6QI&{cx|&O93sToT(Qfdbuff+9?}`a9TPLWclXp;ELZhF7@J zotI`i!-E&wmDF^1&%rQeNF9Ma2b;}3zG>9=hB({f?vN@zD zC)LOGMxq3o{oPg&vR3K{WO)dx_6viU&eCgFJaHb z8RBV{npssaJ^+^(bq|!8f8KOriC#_J+B$5L{+k%^6U5;`314_LgM~0qL~Eonn? zoCzNO!MyaH8J^1n^63fegRvz!r@^ZmrtEGxHx9vYg9YBqY@K89S}R2k{|>dngqj;G zwlD&`4Dl@MspP>hPU)Wp@_2kyBn{5`0({m zoQ4i&smX;#C6n>!x-eieHJyIPOb#dr;TV88zdPb8iUbU(VxVZA zEpa@(LAhT#8L;3O!1!f6ffEh%V;+AzOFlpKHauPp9Q3d&h8kx0J3ldsI6BNKCG9sa z#;U#w*q=r#>19K{N&aH=aFBPTyL`Vtun7{vx%{{yg0k}irV$bAuPk(2lTO*G?(P)1 z#wI!~+*>0wibR{^|B5IR{Y}P`x-PR6o~8Q?JWIt}Tii0P4;SMXuCnjvRPYXpg ziAM^=DJE*owl=ShaOcj9e@JhrrgO%&ROw`np{C$lTJl0_(gD)2OH{3|4s?6e)i+45 zA%`Rcl{sQ)N>-vWCzV%F;Ec|n01DjyhUyOjf=l|lQRAaH;=8i#?@d6;kGq-6@H%u{ zbphRJDi*i&$rB#DLYcWp1vyK2 zjWYzyR|in&B-q}GgC~L%o^)(p1I@s6!Pf$h8cc}yM@QACw<~_VO7RO-*iRClqhTo3 z-~Y#&g9>iPcJqhBEBSTdIZ>`llvEdLQpw(NcI3w2r0{{0j!YPHx~QbDUWm3s65!X6 zbMrpW`yR%N$bqN_LMb7>a#NY+?+*FjLf}2{j)SiT#0w!IySwHCrkC7V?<23vnXu;G-dBH0l+^f|de{bHT3&2)E02Ht zNnKvfX`9~Ond7O7F>t-j?nksJvcO>kY^X-hAy-ti%+}rC`ytPPl|jZ6IOj3&egW(c zVhAG7Q`ut@hw_^;B^VUn91Usv%mjk4hk#DGY|x%Mvz7UGtMtWj%c$G4XPr+?f_i@r zXj<=bz?r$lyL$vS#Eh{tX;gX2h{j$IHeW}?Np`{<5W}Lq%eT%DiWkqJhs{Ttk=5(!8PR{fY8j0nPho*y$0P$bGj|8ZZ}hSl@e& zrcZuDFTN=w_oz1fuA};})Urg;GeMaev=N zZwpwgX_ofc{pZ(97js}Q9jX5PJuED;jqho3`X?W}^y(>GK2zi12;Z@bz&;s#;d7<5 z)DDIktT1~!$tl#(x-=@I>~Pfy`qSoQltun(lnAk7(?4o9KN}O)kbZ3lBv)x@_%@ zG0J4X{F=Y+@0Lra3*Z^uoLLd^oLL96>?^TWqJNGH?$(n`6(C7w0-7-x2(1SN8{vh* z%cR=;-6}*5FBDGtYsl8?xq{!PtK}h*TdglIH|LkOTRKX;4OfgU*=)DlFs4h)tfp&# zzpX8%h?gps`!!G>j>zNp6W6G!rpQyHiZ*@AVB5)c3OVDG z;6w`M#1U<1QDu)m#kawFNJL_F>GXu)DUT*worqS+fVF&%y?yYU1;8L<__i720*^KT}{ZPPgj@F zFs7i6t*hV=ZzspuXO?0Z8M9Vl;$2&J2+A!NgbIPj@q}dG$#J12b53tLB04Pm?SJ~@}@J+jl9bsnDoB(nLS zI+E%i-U4^YIL=FcTDov%=)@c&nl^UQ%HYW?kf~-|T}{b8?8TU*zS*fchQHa#HGbf? zYjV4NNY`D{!$3%y9RMmP0~|r9dR+3Wcu)dt`l@(TEI5&??@2EB7FH6=z!ln;Qs{&c zTez+ZqRoYl=GOqAB^M3fp4%t(`&RjeZ9Nh!`{{wuhq<5v@IsH)00={<%OIjA^p~g! zywrkrt?=8|6vKM3#kAvc>4Ax?LB(%@$8QQV@N)r@*OtH)yqJ7`({Bml<;w}?!|k3i zJu+|#x6TbbLeR8HNtZPSa6wO5&joN*4Hff`T{$U3(fT>Z?v6oJ*yPjgkAbZ7N{`^r zBg(%Dcp%H!Wck*h)|K-AixoI5=)#&M8^4BFUg8oxlj3-Kun=hn^W3y#f|N_)lvAzd zF3~)am4`^rOGxqOtC@P6cuXej!T;v>r+c+h(6eJw$Lf6z?;pyg>Ufp#s2JVP?;p}5 z?|3zDqhCP17On;J2E(S3E`5jwI&{G0l$@E#Lkm#_n|=G*xW>oRJaBQ~fCX82MsD(maeg(QhoC$_ zQaRXp$ai0zxD+OA8S8cFG#ZUr2vcIo(Q}Z8qJFIxMRl(D4BR z5)vvH=Z@8#Mg<1Tjc0zS`Xcw%1LhwIHaVvS+Jic+lo9Di!`hHKm()zrIqA@}(03C?MWPh_EfEg+D&eQ3>Z zx33vyghfy2-=oNGI~4Ajh*Z?X=oe}Bb&1y2Wli9t?o*UMTqrxYQ$(kyJ@oaIx$~~d zOZ%@Pe)loVC%W1fD$FOebq6SekAIMk@bd>`w@W(n42AKu7P+|h;MG??>l*@57YKoj zfA|9a3d=6!XTB~6>_tB=Gf*3BPr6j9EeC5?ye1z}cQpDmQVE2vKaoAPTjTY`B9!b_ zuXZbS9LW~aW-6*XRuG@C?F!C*!3Xg(r|g3|8Rww5`)HGU+!QbM^drbP&^()ER4PMl zH33A|+_^=PtTx$dkG|G7f)uP+=b zo?Zsqmh3dxT;m(Xy=3AsjbG>rUg21`fJCb3TY)Ta0JEM$5Zj5HXoZG`#X(z&i6gu= zo4g;|JVsaA`I|InrkVm(Z3{?b3-yRKr@L^rjBXF|m}w4odn!}=qDd9fvI&H{oKRd7 zPQWJbxc5l$i9fYO8mo?yGAY@e=qWlNt8Ggk(*!rqO%Xi+qnxHSM~Fl}8#ImLF4imJ z{cSPpoy<5RQ#c*k(d34ksmp<-vx%$|DQnNzUM}ZHhL*?S+*vN?l84h zxMPMP2cfM0KM0UBBiy`nZt(|p!De4BHI zO~b5Hp5gLs1zd^~9rGSc@-D8a8=RwyKde`dM&+9)lM3xK1&oy#iC?T9N_nopnDvnv zZfwoBxSA7cYp2b|zb~fSzi_BXDHSY=A{z@oyBkT|w6@0Lo^9LI+G@fTTgBW*Z?6Z> zpU}I>t;g`XGIyJ9O}!6-O_S^s(nW(%q3Zgsq7L>)>!N}(Yv~1kUM+}@S3VH_)XL|0j3C?;;D`C=`Y#frj^nyIK za23%vx7WZ|UA{ub3>;9*!0a56xWoM4Yx3-YSbn+K`8O|Ws2RYZk)Ok#d6tA&zEYya zwbdgN7?89{!R5Z(6CnUY&c`pGZ$W>9Pc}qnB?cFDPM!tH7uDCBys?p20rXv=k*`oI z1ki>o{S@K_5P2U&$`|A^H_WY>^(3DXkw7r>je&!zvs+-Yhf^)SH;}APovcqDr=MM# zTrXzNdzlozo47<7Jl9EYwQIX8qEzX^`d=&4ZY@uV2jlbWi>5;69qwbTaGy?EF}mj* zV<^DhB8pF{jG^8Z5dRoLf!#T3cP^THRE@*Fb{xl}#MYVkd;zY0U!i_I{{9L4JzG{p zR1|_e2A@sBJ(CFn7AT0@e|p=td^szbgr4(OIekI4PUq?PPwkQC4}b>l*9Jhk28@Tw zHQ30?vYHjzthvisDqAMsF|v&T@OKa3CvO!WfWo$#&yMPr^69OEB!%Hhk6!J&h1N;J9#>_F=VcGxxQ+Yq(u@i+!DmGd{_rvtF} z+b3oR$0c}6C2%iUAm~Z0688YEi9K-XL-Y;!qNBT@=p2_*3zfN(YLonSrp!q-Nx2R0 z$qDSJd`w|amWo$gNs~J{2USg87spd74w_r%%p*dQQfDNVLd~|=QQ2MiZpPomW-pa` zh)>DjFHZZ^1~uEy#1viMQItY;&*Avf7z9SnicDkX-O+8ydLdu;w5Fgkf9 z27IY0QJWyPU~+UqoQCxFN*WzBe46LJiwhW4uCIS8WiXmNRoU=e*PwFiW=g<|H7aSA z++icrmXM7E-XiEzrfzXt8M{bgOiE=h&qaQS$2N3z{sb#C5qCBQuR@vzTY5G=?5?^x zLg0EWL%5|NiHqxwxUcO?ZUsQ#3C&m^s^OLTy#ov1QCKLqDkZMx%E*2GW-TXo(~LRP z5oi8BOl+m9E~f+{7bor4HrN_T1OWvTE~og+o&WXTv~Zb;{$sB6`!fJp{d)qAU_Z&% zAQfdbT7|ffJ#zqb+!QD+Zn1iOX`Fv*q7;?Y0+aN4dF>UlX@opO+r>q;cvh-{!c|I! z!^v19aC`%)h;QGeh*oE32_|o>OMWK&ok~gfDFgKmmU`u#7yR zb9mw`i7kCz>zX>NsN=>|?3Pt<`NX9(wbd_~8$_tD$*b%^<|?(_^wsC$DMfcDUn?v* zX=7FAXdv>Q?5?UfjBN6!5)6zF7Pw@5l1dsD9V)2_xTo^l9|}bqm5iUwY z5?1Pth(DE^C(X(R_|qe*#N2{Ll#}?*9mfGI=E9d;K?l$cR<6k-3_}^M&I-<*e&NBY@;GK@AHJbRh(1exyYp9$O9$XA)IM~ zj?qKhZ9|_dFV*a`6~UCM9^z@Mn(|V?q|&(D_zNT^;059wscj(@x-^3yn42i~1(>#a17q3PXOu&OL+cOb zqoJq1l}Tb+I`r`wV2M8U0V-3-xziP;DGv;xvs%vgC!7x`Jk@`YO1b!3vXsJe`1ji< zy!QpuAcodj;xEQNXtgQ%YSnU`F<(mNY7J11&0H2AEALGkyt1+~w&*XU1BDAz`1@TPB zt90E4Yxxp0GtG&TavbHX5V*&tbOyFEN;Mv%RYEgY8?Qifi}`7*Zv>DQlVLbt9GaDK zyi<&9M*PyKh3^%0;6Pn-As@T0n`#LhSl6FNa5mqAom$n`h{s9##7HiNe^JkM7x^J# zD*I{KC}&yqRM+8T3&KHwq)qnUfR*ny?@3MX(E*LAz_Ghwq?Y5*n(n(G^a*4&i#YyA z5?7c^%C%nBUmtSJ@#{xs$WtxY*;n5O`ue8vZ{{SIz`*!PI05br3OMq`OGQ|w&*{6Cd-kJxqMsz04%}(#%Ch?-xl8b4*J%=VQLQ2=8jJPw^&b6OKE{0 znRf$qeLq->E})#GVG@K5a}#>Zb(fnb4RE411#nu4MHX%J*eZzXH+La zs(+`WTNH1;J1A6YSS?McfQTVK?s@hg^geV6_Kf8vQ(1{5tICJt#X);)Jc1-@{@||6 z1nR*L{}1q!>&J;)vD~{K)geMoXDI~SmJSLO(RAI|U*3O_%r`28Fo9hQx9DA+^_wjT z8|b&v_VLI(92FV_PHlzIJtDWdZ2dSlLX&yB%&_DSR#qq>oqEJYB&Ug?LS|ccnrMO6 zSTshn(xpxOpE-QObO>!rEaF169NT@Wws{lY2>IG_qTyd~?xm%TkGXl#*78bxH*}+=30UdTR4=}Y0C>_He~wZ1Gg%R#&yTcq6<-Y7}4J2aPb#T z?!-!r6)Sv!83*2$Q8VEJ>0$`ug)*5|TkQgfRN5uMR}b_8nrg|*OPJl4$Ac5`i#dbr z(=nmkKIrQc=@^?#;k91*KnOUSX!Ut@JP9%s$$J`JCDn*m2V@BQ%z@a*|9F!D1I@`3 zdIfaK!R&@=wa!pIafH`iwkson-$1!zYma-$nQ{rl_lvOps()(jed3OXkiggG}1 z;yh#$q)AOto_L|E?CWND$3CQ8P}-g^>Y7+Vx|UOP1E5+#!j;X~CUVPKS8+>NFTJJK z8YWrCtU}_RB{<|@$B6eRt!6o8L@!FYO?{m1Tjcv6jt|@UJB$7=_iOaOiiH1Hn#TW$ z{`-H}U&)GFzd9S}Z`q%Dmo?2{KSfYz)E1Yz{;&!ekvv~&4DCyUqBDg|galfN z5h8mSad3hruw8REz@P=>@gjfx@%pc|=@UaPy+wCJ1qV$v=xDJj|kLmR7uJ z@yF;r`-kc%%59~0(3zip$AI%m;*eoQ3t{Mlo{&QK{`%=HXM9Fss1Y+~B?~s1F`SH` z&WTz)YtA?w<{wY-+f8!YMi zSH7#X_^E^~keR_w}~VcoZyR;8Pxk8 zr`kE}EX5MjSow~@q+bi=7Re@J!UR#sWbw~6q&M8=RD(WDQJV&7P=rpDIPLFk4MYY+ z(8=fqDy1WVUvC|E5iP}MI+1oI`s-aR9$QD(gG7`qQ(G0qp1SlGQC3(f2k9=oV_*IY zg=6K@qbzP)O>QpXAsB@}$;OU-RzOe^lLj$P>9cIYV}PQ$b#|X5Uw=+^z-+&XY6jPB z5j;6VR=|f#u^+#}4s5Lb&9g=bB>q`zzsGROjuljZov6Gh}$ zC5#0c5yfp5!tuX>{s)r&gZ>>tzmUBAugoFZ|NS8SO`{}Mvj2~AUCHS;l>PrEpsAdx z{feJ|c#7Pa5Q*YI`u)M_(uxwuU!7>z<^aq^)11n-p3((g78=eULL zw;T24?~6Cf3)jxNN@dYV#bK-~iq9?wkpn58M@%Bx&-#t#xN@@6r}2C(8u&j@>q~nt zm3d!`p4owNr($LfrJ%hZUJ|9nYg3yuzMFjR1eY}bnq|zyD=7b(q__i@J1)kF`)96ZXMy)=x-zyj9s`*EgYLXU*7PDw+(?OLyzaWm}qwR)}+5 zH4)6md9p2>oOI`X-3@wg3X7nv1DXl8MzMmHTPe$U6hFHeh-D;}ram>u^nlsXhkc#q z|C4PSV}dTc>!eF+!=nUq1w4eV*2UX~xto?OGV-{ygGbyR*kuc+FZf$zpn9ng5~HI? zNo<1QWnV8Sz~?+{BkP)Z?AS@nR7n`F9A_q_x zSlLc8HLjWB5)U{Vd92)phX=mz&0bJ|qi|8L^dzs# z&6`U_EIS(Z8%vL$aogNL)4_ZLoK?Q$L{+-vj6k27=Z80#D1a^G4}BD3%s^jZuS$w} zCShLuQp|%RhU!eW-LKrNTTi9p$Ydihgft3KQYM-#>8;&LQG&G}6oD}r0gp%Ms?cB9!;SAJb_2v- zuSGP`ZG%?d}+^OAcR4IC96UO9`VTp zsZ8iC&^L6oh=-!=t(+7Z5UYR`N#M@kM}{0Ux}thZ!5D!dF+4+VmY=!d43bL}R6Qmk zrYAouDP}4SqPGq@1AbfEwyUQCPa1pP5Rlr+0~$QSrW0#Ru__dMCMyQALn69qF7;Yl z#vYi~HuR#xeQLpHbjrI;e>EP#t5vRMRw1KTb*8aUg*c)tChX6rrju7-g;Sg6QD5(% z*;+F6h?Ll*xg4c2RT0*03Y|n5Sz^LQt@C+P-+aFYQGJ|U4zf^$iAE&qBwD9zt#16K zJ~TTrpA;$lW3W^&d*=Wkv6M(4*W%W&l&CLvjgW9mjzTpSW+o@*;+CL^1f7Zx3P+SG zi@!;7OskQB0IxjzX1x9shs@Wax;^-vyAZR-qS?-#_$~b1?Kb)_Bfq>K`L~Fo zJ?1sj4DnmW^;Hj{)uB5sPkNAJ3QrTHpZ@JlJS4%pew3(3PwJ8swzmg_Fb90TH(%2B z1^`n3U;BM5PVWn+A4LFypL0UiVIZ&@QsCG(8@(4$ED6^a+pSxJQiuN~t5@i*wg;GY zM=-yOQ?R1vB#4AYDuQT9PQuoXpaN~9PuIfFa`{Euu!1CN-oHS_$53Y)DQMO=1 z+9wDu)w3=1o41gna>RS>-#k7_;}Ewh+XEKy9!u}~CDIg(ghGcTJ;6%&3%BzGcFp9~ zrHx*)5vsT^wY?V|B4Ioq!3*76EqP;X<4Zm>Q`^D|y*NO_>y4+dS#3eGlhqkx?886A zZt!AmOroRTz_#|+S^1sBWwbfN>_#2^1k!P&r_?rg@?Bs&)pI2L`$$Z!329HM&GIC%5`DOmgT2 z??$0(C$(4WW?W5-erYsAFx_|$vMRp_)r z;P5fT@Y8<%3Do)om&02y0pw5o)ys`77Pt8O@u>A8ngpstT9wN!nw6@R%O0wgs@2tK z$3G@LTT`H@{@>sJm(wrDQ<=X@bB>+Evl|~rcmT>Z)t~_RHfw1yaztyW4cFdeI5lp!>oFa!bxao#u>!p0XWi z(xAsb_(AF}Zb@@>?Bz@!_57@!*j5t8tceffGYK#2~UgT9KmB>h?60~I8S zXxmtW=o>%XjCr*e} zmDLYO$eRb=(fc2|zUG}}`#-Ci-;pH>G<^hG&pD6dpI_QRDvv275~p(->L^*!Ba9kk zQ8dj%muB?E?D9$rMtuBVjJ;!wCQ+lV-L`Gpnzn7*w(Xv_ZQHhOPusRR-B0_>xA%8` zoaDSar;VC?jX&eL(FVa&rv#m|yBV=rzB)8Hd_&BX5>zp*#B{ESQ>cxsru zHKZF8@#OmA5CR%f;pFFZIS!$S$J~QoywGdXf+xl?7L)oh8^uW4HVwm`^|I<)R}k!+ z%gur8$m7B09=D8ox2LfifCrl>kZfyT?Z}KSPpCDCl5mNs{-(!RtHQtn{LSYQWL7iLG(Bz^l{kg7s$I5TCE_IgJfz96nx~MSXrF>fl+*XZnb>)>w z$PedK##Nmi)jyDR9p;^SWw>Dm_WopTUB^5}Q{eGg34$Ov+yECe}`Lz@7x( zWM}@w2L@kufrdfNnDBG@QLOs-@OE%5WL-bTuKmK+rCq2Dlz|T#phvBof#iKJ@&RNE zUttSh9Lg5`y6wm@&C@C&yZysDEYE%Ptn=KgJu)ICjJ2?B?;NCt_|WyEn%G>hQhxe$ zIWYOlj>3ie=>!QbjHSC+HJSdPAueIEEtaRGvDky?ktk|}vCv9&sJoJi#qmL!W0_?B z($bT~$&08&tcwc-5fm(BL1vA>2t9{*z8a_eeBmZ$t|gWrE{TCK)(y%9G%rdjNz-UmCVNKio5(t$jR5SqQF#* zLlmET?NjfABWu`*w74z;q(ku~PWQ-)v*wuSNwN|a#t?ACFM>ANMC{DNxKC~|?35L( z7Z%*UC5aXVo%s6TrcC3{>#Y#QKEI%Dm!X&+GmnW={n!_ApaNS+kfg2^K{9;E68fmn z%>VeykV+e#jsS%{Jge9-tMd+cvhqZX0ZF63H~EW9fn-)5Q`Mn|}Cn1%@OtX*~`X(dL$LcO+iKzt`n zWVUd9-yC0FN{)Ar9W%osAT_$qD38IfJZuE}$}SEA&oXP4e@r#k(d@Q-81k+{k)e|; zjj0qXTWlOD9E%&}j9@V?(GFEZf>76$O#^&+t@+OeV|!!?(n5=w&bZb#!I%quW34RNcEpJu z>BI|7)Z%V8;&865Y`#U<>J$`srRKy3O^*ELR21k0b0bmW5_?FaOxqsiPK-g7b;Aiw zDN{pz3~$yD|2~0g$By%qVo}(mB_!G%keolJ9V^R6=F;ASMvau1OX`v`_bX8|EL|s$ z=7d6OZbZvj$6{Otb%mBX+iA|IQpwlgblnMJuK7SWM`6ewz6HEUS;1L_S(uuV-LP19 z7X)}LK6X_~-BgEkmIXtI?pu^;VQ8^)a-)`P<*t0UCa6ug=}1})>%dAhs3i#|_8a)` zRFs7>;9l%wIzZJ7!fYbbZ7^=mGLpEaDrpeImUx__qo{=Rw6#j|=%i4ts))D}WPqI{ z;wp}WBh&TJ8}~hd#h44Uao04(T`Mp`8A0uK)DU~BIm~ZCah*wB1HAIds+dwO7ViX` z_4#>HrTkx<)NP`nSwo?DADadx@e^ltlbOWj^8riEn=2f^Nq5$AL?NPTLG#LqRIEg7 z%ZxPFWb#Mxp!sIqsHJUEm{#`FktM!2~$=ZSaIL1^Yf?T)q*_zAu1aV^v>p=5>mwDIO(MrOyn*4XVXDKX$f+A z7UeYzvZ-Hv5kFKP5^3Jl-;&ZVO~6xXYrD4&Pp#EZi6y!kiWSiz?C)!#b97d)Vlp6u zmKCP4^{LA-NK%D$O$VvU=wSqFAhVuw*0h%FXjkRzpV0a;LgZ>F3!MAwu$3s8ynAa5 zOVj~2lbdq|+}YI7p)%YvPUkCBYE82ke!gEs12>?8Oam4=%l#Zq^bd)OQQwBHFw-y z`(d32gek2!3e+QCj7lt=)s~2;+_%=h(dsK4blPfs4*J83o7mNtmm0IWx(3Y^b%p+F z@W56_D&|(u#%y=?Jxfsn<9tx5<4zIo>y9R@0Y<|NpX5PjfSZsilAf(7%p-pI`?}s1 zfuub(H&!dY>X>!=aUZypFBXDIn(7giCU(3{$<1{cg3b|4>OwE>tzwMNSUR6bPPd(S zAPior=^`sqI!QB3+VVSzlIG;Mffg88et9FB0u+vrg%dYQjJf=gJ!x&#AmXY_wMZQ5?RNlk3q6XR+%m+)$TUTOCp7sJ%}vQR z0~)+iP{QwHfXYN72DVZQNMa^)cL5#KGPau8n5)1>jDdTCE6JEtA30JCVU^O-I_@Ye z*P^DR3~NmVJ08O15wVHX15BjY>K_u}6wzwQT=W-@78M}Nlr*eJDow8`&_^_B1v)J9 z7G2@W8KyXzzvf<&5qJCDi{<^499tFovO+(Z(jadVOv<<^lchEH6LgX$HaO zu=EMNru}v(7f2*{vcuO%WIQ}l0KV`NP>{{Bl!H{X)3T2-8=r|Z37YcPAVz;EuvK)u z7>(k_dZWonB>Wt=4MwZj^LbzgTQxuxyje;n&YX#Cdpb&cCI)er(~fHV72E_eL8b{wm6>m zRyG$RY0>v$%Zg%RESCZ;Rl&tRa`fX6p*PRrP4AV!eO;N(Qkth^rx~)K%ZBIHpmp`Y zX!OK8^U+7QqsMo#m1*@A2Ho|BKXcNmlBT6>mZZ>&Yp3n3?cM?dQ^t36G3|7=8Dvbl zec^DB?3)`ZQC%`QD~e>1eAuN3=099L>pA zl$Lq^;MjgK=_pR}XCK8^!nGx~6@m0la=J!1& zl~lwVst^m-nr&whtYd+UwAsdS`uOx&>{U0#9iFbS*B)h*vG_LOa1A<>aBF{qX~{Wf zfgH{u6%zJcL1mR2W$mrvcMSJ`(b!F=Ffzn)2P7)w>YC4!3bimkgn~YDLC8`Pt~Uk# z6VJNb3YO60JBjKDQ#?wxQ~wcnO1vbYp}=rguGl#@K#2e|7O4szR9wa!Ze0Tp{&s}7 zvl4yR)={Zo-9F66wtN+#X4(fT5DL^KX@xn?TJ{KgCy;w!LB;!h4d;y`qLAVfeE;vd zyK+!7gI^AYGeYcq$)4yps`L2=${%7(Hm>!)sP{0%HOx?+f*MQ6lnz;i-&$XbQPPX;kI`m+3F@EH5~PgUk+WTvxd8} zr*4+JbhFvDUb$Hu5>J;|9O)5iCzJ8MvsZ_^AhTEIyTYgRi#?;>jnm$anEijuR-$Qp zgV`J+^$QT4WjCR%-V5|I*1*koL3OuI>HkFcioF-?I9IMbGiUghFWmiVJOdqTw>Cig z@NXe3%kvoPyTgMLSY>1<6hFhCtn0?a=^f<*bori#iZy-pEa=m0DPY~0Z+yot@XNIY zH0~^x>$vaZdy8Z47Fpa3;Oez~IdECR^hc6vQ0Mq?-_UWWB8ad-C0NxE&`S6S||to31>9@fmYQ^I~SMXK8W|Fw-9f3 zmDAvJ~4 z%5GoLT?WB3bZ7a%&ibjR=Bh)Rd3$5RE#li!cIa9u2nOB~rIFF*P&sUYtBZK(x>x!o zeZJMT=yyoEoLuP6FXMMDne}5bh@XebAP$_o4ynPVbv;%+x|MTCT%?zs>Qhzfke%4* zvfByh%2-QHW&W8Vz^caF1-ejf@9H7vQ>4-1NLo#G4V1@GudraL^hv{a=F$p@d8Nib zspT0gO1~c9Ls_8!UjP+mT!ht;%2DpU`>pU-IlL0rHA&lu(bYp}lfR>trXG^=vNR3s z69N3EGb9}jt3kr;Q`tQO()C&e|5XvvwW)(o@r&H-UGb89YFF z$bkc5+t!tL2V7vG*<%1I{R>($z3H1z81p9CM`8x3_hLJ{7cno{1oU|sl-_woVONNR z%m`h2b{V!*{j1Zu!R8*-&>cRlLxpU$)?)yS9Hg9iXIjtjM87xORXDwwN*zypuUb0M zdD2a?3w07Z<{Ux=F@}Q9CTQp?DySLq5dzL%1)f4dwPPoit)&Nds!d0+{odYDMsB9` zD|KB8BApukJe!`fsJu%nvsed5y3U9kEFx115pGrQlbvYPg=XbCkPgH(S^dN_x9+ow z_tytPlVP{2x({N8_d#wib&XZQFSOBDk`0ucJh3Ar zn}+zZAHpz}5r=&kADpk0xOqtrov;*Bc=Y0^N0z7@s}%q}+-T3|XU}I3%XFnBX0VnL z|MY~LKl~vrmVCa*D3OFWh8!De(+3qAMm`qo0KGBgSGkh8r$XIGF0myQ4)ROKPODM>caRnMZ3S4Fh7|PS5eiWE{SC`avOlyhlSUr zN!yTL$p64;B(m#+mM>hF59@1&K9;SyY6iFNk9%uI!x9M&dh+E#;5z-Y?f_XBVhycB zTO69N$6yYt_aMxT^6c~W5YCN{?}PZ_FpTUCivchJ#C-_q`#$%ipJ)ujj0etTiE^3; z*5={)O}ZUvF!NWM%)0a9LYTO)988Sc6Jl7g7<9T@|J4ud(wad7Ml*hYoYWPrT6Q#$$QFX zgVtIhJVkWi1C~|?vp3BF-R=xMrF!rVHhTAQZMeHDFM~dtr1yO!X`THEvfjij z57r7(?*w`Jq49kY&7UCuOcIXbeS=(nlFuB~8}bLh!veO>Pw$L~e^8=BexH!QLq;2E zQj8raDn$;DOmYg(2*zthp&zp0k*gnBHX@8i5XGSz;Zd?5fHlJR9iF^}=F|IQ%?$doeg6{#o_{yv#l8%o;% zUq@cPCica{4CP@Agg(a=3na(=Ylq(NyG1$K{5`J zO3I2fHV7>q{v!5V>I^o*Sl#EY_4TC*@@{B~b@R)1pi`jJDGk8mqm^y(*&of$1x%Go zAzoYDQgazc2-cY5m)%2D%FzT!%gJWb~xEjUNkkWZ{Qex+j*7 zASj3T0a-n8FaqTl%YKG)O@NHrf0BkHAFGb2QGDljdUctEo~{HWw^IS{h2Z(>%% z{d|t>kW-QnC!cKqV>VGgH*_s3t-`Zg%U%Q~qZeQ*+y=q4Yx1>9BH&(AD|4oi4E?z% z#H@CoP@d}2Bi-oJ_heP=EXU~5sVqASO+J#rp-2}Ue&iFg&wV{qZKATiUtLK)QS79z zC!=2hU*(m?pNwN+;)%6AM=~Ww_+~Me4cq#_9OMt>{e;s6aAgknTjlrth6WIB7XJ*< zMQykN(6Lw68Zs6?&A;3@9PChaoCu zj))#18cpe2`U9lnvG;+-4q+|mo|q&U=vqGmzEJ}NLp4li9Lf}hKB%dlRf2qkiWjTk z*g`kBpuv1~6){Wr&o$WJ5v8yZCu_G&Qc5yaLNQJ^ReYLW9!jL4L@lDf;J!-ff$U5s z*tL2Chb~CFP0Z23*f;Bww3>`i=3oUnjfY^ftsqYx51c|{(afA6a^Z}O3z@tj#T2YI zM8^(%+N@&8TpeU)i;^=(6>ITp--6W;{{Uj+I^^v{ai%)*-&US596mJjb!fJU@p+`( zj8$H+eYn+M26SdiWb!j^?QWwsVl?l2k6|)ru`v-Jj+mDYxyU@__$^yr(e6?>x=4cJ zu3Lj<@Rk;bf&Fp5f_AnA{`&7vIaON z-rUT531_iUta*mbY=ch}qnQ^KUDhD8>_$Ka-2+4R;JDqSk@XkQePxt@cblO4Gh<&p zx=<_p0W2#$POqge=rPHrX_Oc@_u*|*x!f!y3abImc-7L5oN&+Mu+a}!?{5teCDrklk+J%=(28OSq`M7 zwBf(qdk9;}H%wW!;oqh_aOI{;?j87jLRC*3%DL@H>$Z{&8wrL_Wk-p2GEKI_lTCjq zr&nJC{?6nl+6qu^e4k-8?fCJ^dQh1mT4L2^!t^!vz|>2fX|<=+ z+QFJ>6~MBTcx2M`JHs7yX>@O%ZEj!_YpH#dMVrwq8)4k8$&_k4-mO7h0;gOCe>(9gUn9)axR+_EWN-vf_d zJ6pbI?YCU^+ZVs~cc^$weH@m-$w)fqHsLWDK)Ny6`5&jafw^!UZS``jTgJ=m<7NC} zu8W-QXIAq~?YsvEZvRH&iD~Myty=tgc%dgDOZ|J)LY1+sHLWBw3dKh`q}rJEm!XMm z8R1gjWQ<2r(Jj^%cj-Mu0|s|Z`(VV!pLX582>#zTIqTBk{LCm$huZIC#{>SHKR|5) zn(Oo7*z4{4BZX1Pww1`*39g)A^0lDy3qw+=`z2r+$%nd1;(bb1QEI!M@egZovQ|o3 zfyJhj9k6(-xdoVfi*)f^f2Cc$C$c`B9Y899f{K%Lc_uu zVw|d4lG>c07GIiZFOiU+aM1fTmYYRjam>^}kbVbqDYz+o!Mihxnnlp%$X(&48=mS< zUQm_X_k&{0r3v#7&z2u39I*&a35>W#;iqd?bVXSY`XbE9tKDL;rGDL0k)Gmy;ZT5E zX}O~RZ3^EOm)EgJvi#yT(Uf9d@yXb<@GxxvgxMx0lk5k|n5Ds>>WvL&>LzRJ9a?$n z$Sf3QJStj%JN z`9*9G#%-&$e)g%Hi9V0YnlhV1Sze`%dm|m631qX+v#c|fez<+AhSWX$TOmnwj}hn} z(SD7kJHF=+95?v#y^H6Mm|I8N)K+H-`*veQ{u-WTtHx9yJ^<~`;q3JwUkF<*Zqu7{ z{iID?vA)cov|PjD`Yd}K!xiuQPvGI=?d*kMA>oW9w$TevM;!FIoM9`acn=``&LLc0 zAcvAXEB#s>`_Mu8o)9o1Lh8@k@#$`&WFNUL*3J^JAK5andKu|^XSh?Q^+nd+7XnXJ zH$K7TaFyG-EtGaJTkB)Hu3A{<3J)`mlJ1j2VT!9jS~C4YVhKG3nHVV*6K>Ob(+|A2 zsyuIeHZ^ZqjE00i-iCQ2PDpbl_HXa`nia|>w2=3FvVT*y!!=$cBCDy{&sRMi0T01^ z;rwaR3-Fi;$^+~>Q{BW^YiL#CDM`;u*B^rJn%W+NDIwovu%3WK=h+7=1qgIhsW<-5 zN$2!Ga*+33y-6F!h5Hfzq5y90zkeY#7mJ`ZVS`qvxb9{2;jh+P2w&y|}5 zjq?$MJ>h8%523yg{0>k&`JVPD{@d!Q%RpC3ej-AGnyJTgcfMTC$|-lQ5-rYBBG+=Z z#FaX_H|*|#)T60Hti;mi+}gfo{F7tAn{|EN6;HuHD(P7>_rn1J6W4=Myw}s;&-Kw*UcP+M1`&JBI$o_QQYZfUv!oCx4Fr!v z)Q<4|CtuBueJ*$@tIXo|l=*qkw#hvq$;-{!pT z4hK3FgEOwlc?^qUWuFBB!%Jdu1qtS>F6YIPrpWg;RHj^SkLYu2Ok}g#mu-X~)!qjD zeTZp-_SWwZL139iBvTwhs2>x7_=M~#j5p)i2tr}LmmGt7Pf+s*@QmSXrg+A|NMCC8Co|4q#&NA4 z?6W8Ij*R*d^iNmb+D}6r>$?i!*D#H6M!y&_yKSq1Bl7q%V=`V8_Eo~$*f09tF(48~6%akcpRBi{hCHL)Je2z}9Zr|nJIZ+11|dvoqj`Hf$` z96rDICJ7GvP2-<>ufhE}K6nHM`i@?$aeiXc#_rbeK7r-V5Uqj%!<$Us5$v%7RkMfj zR`8$DwV48ywTB8;*?^@@_3xUtSb=iA$^5mtvw%hSN6Z$zPjWks0IlxmAF(YNzmK=8 zO}|h08;?)98}#qE7mx3{7wQ0mkEDPCeb;oQ`<#fqgFEVFo^^9&l9ffahJ8Y+KsQTO znghbh)KWdfHyZMZHHHu;0AA=KuN`j9$l1!YAxt5FlJul>6?Tl)!TM_hs&Cm_3EW`A z8~QHIic7*bQyhxPYVW|nGNi`1e^8^sEKK$W7QK#MHOVimUU?d(>jnBd)!S}lSm5E8 zb!ni^2V|douRGQ1u3D)kH@bs^l3-eW&vZ+F$rMSW2^XSzMWRRxo-Rjci28c;9d1D%qOLFq?aHhSYG+e_2iRM2Z=OFT8(0fJ6`0G+^@Y&sX>4?;%)jR?~O8cqjTxG=F{1JfXuQ8+XSzC1cMlZxpe?}2QO zYD*F&Yg3VIMv!vMBmB4&060?c&$US^;5d56yH%?|n-FIU_U~AC?Qwe4<6SQtaN-;6 zU-g?SKY&!~J)Y`C>S?R3gqzb}JFV)gGCcr|TAuzD|7VQoZ-W^1x8>wUUul^2VtsB9 z>RF?Hw6CcyqmV6|VrfG8Y}sYk?D5E-n^6ZE-mcl&E$ugJw@d_T+i5bB65&-ZMmCB+ zh^2!0Lg&FBR*cd_ucd->q{qx(6SGdHVG<<6kRiNP+0q7}UKhv1$ay3o&Y3Bh)X;Cp ze2SmboA$R$vm8Sk+cp=0c_d!b%a;}BVQ@P&!X!fV6i}t2)0OU&l|w=L6jip{*=6OO zwki1<-L~GF0GjS;hUyRfv{SjYr4^qZ<@UTj@22V9X_oxo&oC>B%-am0W-Bjj%JYyk zR5wZn3mD^{byOF<^OXstcU4OF*>#6#ei|<;-B$$uTjuQ$1 zyieK%%DFh7rrxCJjo+NXZJZiaz!W^hLh6O$QK7@Q)gq!|Dmm5n6-~{-+zW;l|Ac2! z9_!+aGMsRU$@PVBDPlS>l6HW&E=1SKZIM~d-xoT8PzU5ht448@F8lLiYW*w1W}pgY zFAC(9Vc%n#cWX3Mx*66itv9FV8*oyL&>%!}VE)g%m1{`l6gXsf%DuREHAv?ETV*?; z!X&c8Sm;}o>O%5Iqwpo1I>S^=rGfZ35>WgJfV@&VU`KK{6h3y(fF}7f z@d)*H6|}}z09R|&ZBRp@&e18pyCOYSs;Av!(q+KKU06L-LO)LtxvKoGmrSQE$Xzn8 zf~j45nW+-)5Q8aNFM-&eT%;!#?g0UYMfXxArs$?|m@mO5t4NmxNHbg|U9sN63N90J0PX$p-@-7?C;0aoQM;l~q|+-p_J z>|2yxTk{2ibm-Wd*FU@6qD%hl@xDjfG|kgJ`M=b)bko8I#lYjIACWo;T($B_HpA&J zfiKtR)6}(6A+%l_%`2(Y%>PP~YK#zx`A7m?8R6!P%Pa3eu7e%5{qh=UaTqiY%M3Tn zcrHPBOx#NvH*HSO*pQkE%`-KJwPRIHOeB5^kE{~RV933d9V(6rlABQWY1i*t#Y7B} zf4#tm8JN9~lyGLsr{Pu*uMXw)LIdri8X;*PS4SBF7ziEhU8e_g@ zGyCi&)}wAkX9!igc5RD#?1L>xsx{}o>`ixGTCt6lhR9ReBo4?^(hh;4XqB{{VU><% z182>NgC{VjpO_f9Jit4(u%S*HVZ^E8U(Kq~K!CL&bz#$$FD#Ph`_L3THItGsV~Su} zD<85|2<>D>H$R7xb@s=P6qwa6paZicyv3aUHNHPO-Dz@tXwc}c^7!O@Kt*X7LA&p0 z4RI@7XHuC@-G@y-0LJtHq zr1?Mb*8efB=j`BaWoqX9-^4Y~Uxzh*2nYyN2m*14%+Dg%ub|Jvr01gL!y&w{L6;t=rJNVNGiBTb@TIU_x;em^BO%f~1-JhH^%5Wud??hqK_5c(NT z-b7a75U0<}DB=*v@N%}|4c3-nAwX7h`!mlyBT0)zs^SoJ`=5(N$Exi!IjZd95EKyV z5J-k#IJ0vDgFq>ej~Q5;fmlPv=KBy!w*QcFNT|2JPBX>-0P>4}=YK}b3I79PuH=kmfXa-7|4M6RSx8u@Sina_Y{vi)23JN#K}#SB1=3pv&B>WqJh?M>rEL!w_wo(3rCAH{?SiVpehil z!M$iMg>5SB(e4fmwra5Fx45+@XC3r99WTw0$5b^8w4Ved%01CP%Zt{}N*iN=JOgFD z9reD`3t^P{nQ?Jsg4|0|1LxQw+Si%W2j-bVc}U9wRy6U1k*c`+TZuP>R=YBZ8~O$7 zOt`opYxYIol%B4Dqgtu0!N6C5X!p6%g0YdVAn=pcRYb1aL?mOSunZ$Jn*M7;eiR}2 zva6>Wyd~SlS!mHA=h_~{X4`K)3Pfg65w68R*2X41`Smux&v$Wnuo{K6xRO}YsBwYL z8NS}EYs4};Xqo4a`7$RHhY5um=KIf@zgFhE&!`QCXH43Q=mZx9Z~6i;5P)s%aj({9 z+lHL0MVhEQ(qGP)eu4F^gXF+24M0crjYNjf)<7|Cnh?MqnP%HKn5cg6>L_(Xf1jN3 zMP0Oefo-7Ij7Seox!4cPhv+*-hi@CL5$p|=9ENkJ^L%%ucB1=%|G)9T(Va*%{Ld>+ z|39V!|5MERzs7@@rHnQl1eEXyxtR3$gq9a7M% zaS%akIZ`EoP)(+7HPJeX4MG5W0!ylUNBi{e-L*qr#PbX0mnbYOZGb}s0?}1|A?F{l z=KRw<{5xR3t^|Gnlt4Z30hEqACtpox??U;kKaG0qdUI1Y#7B^qsODjT)0DrFGW;c9 zEjP;K`?oj!CuR&m#-LK7b6$68JP>$S50)Q1ungRMWG(!r5dni>ybAk6Q196w83W6k zT~&K`ZCO=~iRKgE<<|$OJE1C|jaKwa^Oqi4DI`3sg zYu&AGJC+y19^4DqS2yh3*gI9;5;ib9Y=Ik+8XB=#b!uv|rA`JFb;unkl~uKK(i#qS zIC`a8cR2W^%?!bP68ocMmU4U{mhI1Ri-O5#zXwXO3|Lddi(5BpX>vECR(nX1_{o^| zIBOhpy>c?y40~Y$rzg3qwN(ZU@b#>4rmHkjxkl9PDqH`?ZK}o871p-l(o~Hr`T47L zuKh}ZPmEnnQN#K0P=?l1yL2wqlPwMIS~_PLJl3Cv}u5%IKc)9RbAs-t%}XE-bhX zX}e+CV-!HB)Uzj%XtxUs-TIPD+C$mkDTS06p;^VpzczB%qSLT4yv0bH{-Oe%BIoZP zR+QMccTyuQ*Pif8&#!PsaUDB`+uCk`$eT62Rz4N!82*5tX*$z=ZkIGR5}Itn=p+Rw{Y3gb=SD1Q?ja==omqG^e{Du=*Obc zV1LGZnGnLawF7^Nzi46XmFq855Aqo@M4DdO`2P8vwZ%<3%xpGW!%I;NO?!MG@14`y zh|`KIsLi->-?ePJL(3h;Uq>N`T_G*b7T&Q+tj&zUP=46WZFt?KRt_ewlqomsb&i&`YHfrQ zNN!f_v|6(R=-e~g{oBSKV}!&e<(g4hE9O>K2-NAm#8mnnS$aVikk#=)7hL+YPvJkX zrEq2I3Aoq?%EV<2Ir8e}Oy!i#`Erc3iF0H&QDVkI{`&0E?oJWhFQVf(5$>6y7ci@P z_Zd?A+SKi&EK7ypb?zYet4>6RT{6*c^sz|HKs#e5q5m@UAWb?p%gos9e^MsW56!Ng zH?{HWL88ie1+6#h?m5HXvjCMDf!i0+!<=b4X;A=ie!I7%Q5@Og_(1@{kyHSbk}Hku zhD67zhIDjica0yV9a?$6)Jca>y3FwUgAU26YLRnXh;3M~Bu##mDun}>DzC5fThkP4 za;xZiH3<8FP3)uoted+o|A42G)0bo~Mi;P*dC{s#9PbD3u3TfIPF=9knS{0{Rs327 zciEQ6&yZaD2K+yYx56_IKfN-NGIs!Eb+2_e&_r<@hVDAD>tx*Hm>hYKqjEe3l(Il! z0Yk7O}9V<(?&!UEBuGtawS3LI@>(PD94hg14!@^S;e;ZVR8 zz@xGwpse|u>d~dBnseIBz-=2jc6%sUd^on3Ko1DTI7$F*XtHBo*vFec1o+&5JA{k!nv{Xst0i561cdX$ZVKplnDh$^-nO=vTN9_Jc z)t53ah+1=CzMmEFfp`duJ4Ygrd1xT$Pcxb?^8IhIN8F!c^xrM}=sa-%^XNQj0QIPW zxIge)V@5wn0NBHw0^kQtyEnoWxUP&>U-ylRRKu)krAqX=+Frwe+F9?2DC*|)}FxPk-I0bY6OhjL70p54b2xPv-}?0 zvzn>25$c+{2fke~5g8Rg*OM&d%R%{u=gUu8c}ymAA6hKqjN38q+jwR!dxszGC=lF0-kv-F3P>t32&>P-0Mm8L++(NLz416kfwZMJ>jN)g864HKUz%u;Q1>h955beBz<$w zU2`~<>?RR{T>HQHAq@KeG&lS=U;e+=fBqkH0bwH-v;Xa} zh*h=u*J6am*B)B8Ri~^}1qEZ7$e&VrNJ~u|Sca8Um4MTib>ps_M%T^MEpu;?35f7# z@_&)QzO%(8vP*2cn90p#J{G z55oiF*J%Y#Vz3|>5+4hCHNv7deU)*i1383H9ozSzblzbuBK~W77xV2s(j*+${T#5X zEx@84Wptxi-=$A(`T@=sgA7v~Whsg54EmCePHW^;qWkMSWI5}I>wx>f&8Xromt$5D z=BlAG+ z^5vS}=r-yD=T!4nGc+V~nqD2AZoe?ji8Jkx;P{$~r76qeD zHcEvCjvrcW6?>+vb4H=F=2t&G6e|2U>Rr)rS^{BB+B8ox{9fBOpA5J4&X#O`YN(Ep ztxsOUuQeEu!Rg4Zay%aWvs$RvFLogZZv1%|(n@>wFUd{gX(w=t{QW!>z=C;m)yd~( z^5^tE#$6U(Ei1{OOPA_*ROO<__SZ}`n7XGdGem>p0rQ%e5zgyxPG#E>gSmuxv^9!) zW7Rj zOw_nq9HkH0Ww8;+M#@}(A58L?TTcXbvM2WZ+V_7=V6UR}R<-}>EpY!w;|lHn>!AJb zpPN!0XhXD>ou41dY}=+xK?W2O;2_a;JS0KE<0L#-x>I8gB#_Mx+pvbF4ft+cgxXDO z9lP3A>*`VUt$&f(Mrk(SXe#aM6>FXN&1wC%%_VCao7VjCS04v+i+Zhyz3>pPr_2C0fVRU>y%-(s}i8=lxfvOV3$6iaW)TOuw{l86@C@H&BH`ZqV;70 zY^%R-9@ee3$g`MBSznEUoTikJDt{x>wxrCIlV6#*6rlE6Dfiw4u(v}urFX?E%%Z!kvp>B@9DP#zq$Bzwh)KD1|648z5B@V zsc9_bY9Mb(5?UpqZC6Q@pbb;OfS}(ztP=5&_Y>@HWu%En#B8f{E#I>^AuhVcFe6 zL=H4L(e6FML~;Qjo}<+F+!93DhngdpQSW5p4sbZeSte5E3Y*-&vr!hjNdq(fc?JSQ zfIXo0O_U@}X;n%E@bIuO6oL5H1V<($JTY z8{<>aP5ueWZ7VTV(z|sR)~&L%d+B=L$<@~=U)wp_y}rDAY>6~gP9zIjy-#2Q8973y z$rU-n_{07V<-2axE1o{&g>XrlFHLKeN;EUC>cX9okYTHLFrg5VlfPUS-4*Ys3Q3RCxa7E_~Z;_XtBRJMH=gU@?qXkOUU9 zLae}BHr9i(=kX;KIv()0zyO_M^G|(Q@P{nWEl>tmgSq67D%t3*>#r?s?gUkLYK%KU zNiDnF6R1;0&m|F0A6($8(~s{SU)fvSUh3Lip>Vsnc&K`o^4lxVz$>UD$3w90Q_NaT zvf8RzM1QstnzB%>TA96VmQ~r>-aSoo*9frD_$Z5;^LKEegahYPeb0$IuueTapRNby zV{ou>X|LYfTH9FaDeZ6V?CtF@u7>y3EwBF;Hg8S-)w*%vO+nrhY}LxD;_8N~kVxYf ziNJXd(WO+{d5qTL55Bq6Q3;#$)ZxwU#l4ez^}b_QH%IWQ-98Qawo|k8p_Y2-dfSJv zclpw>+Qs{Y%hAc}2Vt=HXKiPS%?HG5MZTR_Sw18CxrPp_b6BW-sa>_I971SSZz5wh z+qyudZ3;EO487Abc6 z=;HCYz0*5u=Y|GfR%-Ck)t7#(xPco3`3om^gx9DR${b70DV9rlS@uMvyn7exr^$c?>cQXmE5%XR%E6Oe{IYg=>9|vbg z94_!Lq}3U5+LbEet;wP9zZHz}(EI*@6$Mg)L2u@i;#7vjj3}D&5(+xatF6{- zI_8g05cJ20y5EMOtaQu~%cCt*i3n~andugy-_@dP#VnBGt|hFD*AM&35-@C}-=Kt7 z9h>j}7iI4loLjVP4JX;zvH8TdZQHhO+dH;x+qP|E$K0`<9lSZXU)B9_PTj9+t$Kc~ zs%Orcb99gH9^D0KC8#r1ld=~P3l5s?GJOKq1yDSIELv5MY#696-p4`0WVRE$nGm(H z7`-F7J^62ZU=9r{`uSvDQ`1c8cD{%;%(pxj>qU=(woo>&XsvWsNm@V!Bf5?p>sQWd zVm8DWB2YGxp6HNtbOQ?mCQ>C}7l*PM+O!n&-L^Q`QuZ z4C>55FQr0l%WjR#(F2|EVK9n$N&vo&!Z#v`V#g$ zo~54_=ZLPtzziR;#J|Y6)Qo1Ioj9H?DW})1mlFHT3amY>G$=lGc8-B5XO^0cT&?it zIF68h44#5hPXWtBATDqf-C+57>8&gU{4+>H+`jUigm?G5hqV&Iyo?}3oPzE-dhi&r$QBibLqEi z4N2`t5thSDZJT)K*q%>Evigh^N{VgeUv+tj z=b}Jd@z3fxS6qXm?#~66R3Ho(Lz!sO#ii0648!e9g(R$^4|;6VC*sa^=GFBf3Ld~{ z`K=~GUm-FOe1YKHkfL09Bg(?)W2iB8C$Bgs>S034jsV#VsjCmnUSPR?Zk7Q zG^;{W$xgdXdb_qY7!kKLZc-YhE@-DWqnwfF5%LR5G^=!oF|uwF%w9r&zT@*j&kYvX zXxIv@1zAf1dFALKs6HYSq=4eKorAJx7Pa;{1TvgALy`|kVxE$fAsI<&b1RK zh1TrpalDX-+UZv9aOQ(Q6;jSyMe;Xs`7Xh4@2w9@EMZa3ES4&N^6*{e8NGuOBo9%R zz#^O781E~+9=}7!SA7=UO@d?(_z8T^zDT*GtyUc3m^^P9p?1+rfo@g=I+N{X%gp>K z`e$0hV#%!T~>mo2>C;EOEsHZdIF{7&QFA+KIMz7(RFE7eV^*`9e1~bi;bix<=@`?%j;a`PV=xPE9%7P?F4U|kc09*p`!y;{wLLr$c z$pp@%+_404RB=3Y^ps4R%`{@R|ElT8RCU(6CrM?(68w?EEdPMzI!Xi**dbU5LwTw> zZ=izKpuoF08uG|YI?&V7a1ZmO*>tO9#W%LHb8=D1$guKvq^7v5)L0UW;p3-=0%RF! z5bEoMrpI%p2DEh8clcF<4&WTAS0Qdj=2y&TzDX-5Yi$GjRv>R2>bpr1luxNMkjRy6 zTLLn5dTb|s-$*rl_C17YxX>L(yYvD7&Qo+Q5ym3($2?F~k=a+>3bx=ep!FQ&6^oM` zAsy^kZo`vOQG$nlijt7CGKC zsrN_wAW}Va^f}NL3Q#SJBuT?fppD&*!;0VWw8^PwrrVw@)iIZE-<+ctb8fbP1xbpj zdAA)!(W01DxQ#~mofuV6aOme_=(rA_WVX?gjvW?}+=s&1DVKESNE!NIPmjVGpY+D4 zIglOKje&g>$m8R)l73dm2)XtSy=Z5>-*uNmhkX?7z>U${&BEIm!yD)}-RR$BBWKi* z+||(4m<9CVf}@r<$_>P~JHS>@tllEuHlyTD5}wm}rDN<|wvjUe-Zi3<*vTgY=IF+c zw}ryIQ*}Icc3#m~L+zzhCdr+_Rg z%P3zZJwDl9yh1fN$a)H&muK(tP1i6hf}p0T2!b(-!vMxrAynHg7yhX1rQoj?MYhL9 z(Tm$T2#-_4v;0X5WF4u@)5#^N)&(@oVqQ+sjS~sZ(411I)75=+9CNZ`CH~(~(v>bE zbCnNb4nm>v^r|UD200PfAK{_p@dZa-BV5iV z(vR~@(mnsN(FwnZ^_;=|XWUL8TyJ^x^u>nt4ZOM#8~H4Af+K+PNZV+&7c_i7M2w9X zkV;5i1mbVB&i=thARhW&hu7lmFRYwT7sV7Y|MiPUHg90I^C1Tqkb@67iT-Q!G%(O& zNH0s+y9bU518K4sEsmW`2PV}-aKIGn81rvt)JOZ8pTgT8ssz^KjLds#Hoc6VSIWt0 z*R+rx4<&#MnMD&Ti5l3YjoA7oB!kN5i zoYTAR{)83@`j|FcJ$Ko4=Ur*OllIXfnu})4-y@Ay;kD9DdJtIGEMx9LS%W5 zU)G^#qwQzFIWx{&$xX3$QwqG*QOB%N_gzB2lptm+f*cOX@!~;`P;zWa*&>N&Fz{1P zSdn@m6vW*Oj#}%V@R5eMAZDJ^z_?L;{(9RcC{Ht#Qyx>GjgXc}qM!Su5NZI`JoLRo zoglb9#?}jbvD5MLI~{aUPxFYj^kC=L5p^wWm<@`f7CP{rlXq{GX1Z4zoVt7O)7RRd z&t{g_32^Tfzzz=|T-cJ=^RUfa!jhog4-5T5X#~l0k8wix<%W%2gyQaQUEGh^un-W- zij#>(pyZvI<5S%?(jePb`QUMDx7i*H?YmEQX1TbR5x;Wmz@6p7U-XK4{@Zu_7#6?p z5rkV5Dzimh6!0CA$=-Io@(}`9XlI<9 z)kP-fA0H6JywC%=;HPu}FX$(_+}DGfh*Laaw}WY3LB3$rd~91cV1NlUKm`5#D2xcz z1Nn3KZVpOQdg~qQpu27#RQ|hZx_*1_kBJ)|;AcC45#EJjmtYSUCSED#nBR?S#o17s zG9J3%AC(q|Z4%w14@<%ga0ok&gm^@H!glc+R>NVf;GzSSU++Y}J|X|={cQG=-7nuh zJatYiUG#vzPUgNm_z*4elu*qQKLnE-*z$CWxgBHIbIziRr;fQVjvnB-*mber?#2P2 zv5CV$b7CF)_l|^;c(I^SY6-VIk5hQGf%@?Qd5U=Q2h3uB@XQ$7COql>Sn3sWsy+CC z?fU|^Tx84ZUzL`nDvzQ&h$Q(ePB25vQY}4FHYm^CmBZxzTHEzd2rzqcSz@|y7W7V8 zgqh>S`lFsZVb*Ls7~6}NFxv|B$fq1sCog#o^y!yB?{;%ZlQ>IAxhDr4X?T`GqM9vN zct*QgX^YmX88Qv0Ut1Rdb@Oui6hdacpwQD$8&%6WmFw3gP*m+MxaU^BDZ4?eQmn{} z7xrZk1SKDt%X9jE`N5P6PqlPfx=vyfn4Jr@X&&-6u zI!|Wk zI5fijyvv;eAuYJ9Xq?+~sY|`=` z?lYzS^;7y!c_-0~x6zZh*|4`#mdDyosIedLnjXXxy8lNoQ1>qJ#m=~!hKpt1!(Zpksi%ffekxK?xlc`| z&oMh+n(QyCaEfJP$s?mXd$Ral$rl3TE6&1Ba%B71yW5_S!S^th7g&kiN$DFCv|YTT z>j97l2)op3&0x4sFCSP|tpkJ49+r@+qCYhQL-P4XafM{B6c_Xk>b8~-OpfB27U;}ZmLAu97c7^#(@co#x8bZw$ zI8(wWgP$c)X&Eign|PW7rc52k(A6;sY)UyM43OpH{|Rfz{7T-tv>K=6ljhgR-Ac(8 zpN5D79XT(LvOZ2~!6Aa%{!$*tl9b3*7UD(-l_M9a&WCi{CtFD_){q&QhKuKql(8MHci5nC{7E>tG-Ump^;7a}LfyISZa5~{OUC$lA z+@aq3Sa){&YBK@&Mt|AXzm_;N_)Iw7pTCC;{|P+JtZmwShyN@U85Ra#ynM4%=E!ZW zaeR>pGK!b@8vbg*H|EZcqfhT)tIEU|B^mVYTMzgPHyvXM;vx> z^y{emFX+)9Y;2Vz2NJce7^+tw^Fe6?!#|?+C3}d);&|9<5uBK#$q6$aj`v*-#fI(G z(&ZuUUfnB{E%c(DfrtWuQ4OlKlxKkR5OQ` zS=^_8Zi%N3%BlY_=&5?Mn)FD7P2v}+x71AxU@2P|?6344y&#q1o9yv!E zZTS;T+&Q27&FrhI=~|FS0-FUlED%P*@_$;zEVekS^EJ;HN;=&Y$IRdSPC_eQ*7w4D zAO+E;=_)9bc3=@dU+&~J$v$}_Rs?*6Yzvi;%hO3a5^M7LW|I=!DffSv-S;LSxmQa_ zRLh2AXGbGivKMc0?^Gr0@!L^!IUFFGEc$TY$0@t+GdsY&T$07lIU?9T@&$`mB;G;c z`!IKT{G9L*q%{8eXLdK+Wh!qD69|Y>;J;;e8UHVdG9ha_Cldi9XA3*qf91=vRkYNQ z)c{+epvVLEkr5H|1*)*ZGTn+;MT8*HA(6!U#m&wDI0IuwWHVA-UjaY<+zTna4pqIk zfR^$~c%KU)KMB8}%F4e}#A%v&%b`;oX1Ui5vu=}kejjgGzo6Zz?I#>2e^(s5ny7ik zR#ok_F?v;!ZkZ*@6)W81xD7aRbJ)I=7>(kCdg7hMK2{ZP99?YQ30b@_2!pTASRCX^ABN?TNK*3_K%>R+EfFXPa3Nwqm@ zNzTfl`>35IZvxV_VT7YtEUKj3mY1pS!VhZL{Ht^tskJ5E>`BEbH1m(*YYpvG4c2_U88|0vUCHf zLq_eOi(d*8h6G~5>ErvOz(F>hPsW@>U)ZLo`P$x<6I2?oz*&mtDcy2W(%D$Rr7i}yPI5o{#pVC~p2ThpG8(^vAQno`2 zh(Y@2ZB|8)6hLB^kQeQQT&fq~Zp67Dl;1}4VGWV6Pc~NG6b<#z<%02JvX)1`YOjK_ zMvg(Y{)U9)R8=~&Jmn-EPk|cQ3@~fn;>r!gu zE+B+!Z&=4aZHJloZV88_O0*Q`YZkY?#49TfJ|iD$fY;zO2YnC;w({8?0C8a<+QGtr z=}b*_gBnFoW00|9{ER2D>04(Rr>^pwW^|q=uI?yNR1Si@x&*|qJ^L3;R`-Vd$_>JK zg$*@txp|5P982moUz2>JN)o!v?BNL&Pi2Fc&FJbf=q`JNEISp-IYnAaR<%k>v6doH zf{vm+%$DYoj#4(3zS{h1^dm<1Iy)I_D5MNYgzU6R6LmNdbu0N=MwmYTBf}RR_);B# ztu@Mt&@zZ>GI2wtyBPD$DCl7|q#{+zw3*^?cJDxUq; z%pU$(1?=KpBYTfC_~Lr_zyA8@ZwQv6tk$#+DvBS2eEGd`uQ=h-IH9>jXdl4yW3gS~ zeFv?`@vA4%1gPzlAfe&>m!Rto4Z|9KgBn~CY}r1)j0b-^EhsU|v1LDY_0{i1l^LCA z3A5?q--DPX9-p^KBdMLWiNY~qDPM_UV)W1+E<~SLU67zB8G`=c6vJSVFTp9TOTDkb zGxKnX@k9^LA@eK`{&Omm@%>~`cPTOV63LLTEZ{q52ep`TOXn;a^c7%f+ugW188Mkd zqBaSLC_{_GAp?`?kU2`9lY=pcCa7TyQz&MTUUF0H;4f#=7>i*Vdtsc$Rm~<+))Bos zbg`KG4XTK+Eee`nNuF^amG_M0?l3iKpOKq-Ua!=rg)ci?!!ENE-mab?c4`*1{{lp8 zZW+*QlLUK7A01yb(7nWg1NZmO?U@FfV1jnq1D+{1Rs>mOyG;qEetPzO9;Uifbq%ab z87J6`D=&BlPe@^VDXmIa20n2)#KFrrxY3`)(}r0bQ6jNM@YBeLf585u73ukjh6K5AkTMJt=AvmK| zTiDae=0)4-PkbN=CfY+26A&XroCb$;3<;4knVN1=D*I3=`T^roHTy^ut5QlVSCq*q zpBeGx>&=HkbgY+M(v&j4m<7fRaHLhRV^)%JpJt-Q{ zqMTevaK3J@dMrPnwPA;HU2d>G^#}%68KjiHA6KsXt&Zy3jgm-*D22qzxm_jf09U6-~Sk>`0`Adz#^=n_|7pu#}q zIN&649TE3GDR?*rAr(5EGQpWPR~S>|e4DH7zk(~98DJTp=h+Vm$9lQYY%W&PLq{uF`|JZ@ld8* zNU7rRSNVW)nFES9cb${`Pe)#1Ysz^7zZLJ}M9j_Q5$wE*&mv`1M@{{{2m=LulCR2_ z8v4~_!p^UsAZxLwfD(HZ4RDkst3yS~SEW3iQ!tH)T8i#J(feRzaw^eUA*C(P&Ew#* zD;?p_MroroI8JRf#;#iUix3t>HzF?QLcxzjXX_q5KhFgEO)+@$lVEGPuQro8B_(Sy z%c6vZ6iJoGc#=~iqV3@;(U8s08v159cF1XDFp|&D+pS3i zRKP|WfahK>dJd2uolgGo^jw`^ss4yjy;O7Fgc^36&R%HPT2~_W)fa}4dcO*C58r|i zn@14|MNserip&*`E6r?v;unJtd?Ro0r3U|k48VNoMzwa!U55(mD<}*9Dc}rWNiIdO zqQ7YCFFsegh;n8Yv;*~&3lo0R75{f4>pdcM-$Vd2#cCL_#5M%0@i@=nh?Ri<|YFzNb5%a44&yh!vDvs}S< z8BLW+aPjZ)y)u_XeXZfP5DrD(9TIy$q~$0d<_(tZR4wyrp^`#Qst{hqMEy%e$ng!igBMOE*4zZ*{H$Uh}#WWPW% zQ9e11)EGSdmn+3(` z-8nXL;IS+mFDx5C~WQo)Q@seIXp}aZWEL@9#dt5+Y-JPoKu^BjT?!_Kq&l z$V@?w(Tka|6Qq{UtY(W~jl5W7ZRnrq{{YR2FiFOFP#~ZUi2nwf|EX$G(Zt@`!pPts zuB^PHowJ>ho%O$5+Uj@#*+F^)k*}mVehWmbqHUnHUD(bVf0-gMM-U@eg5>bPOOS3& zbnIV31Q$*GL6k!UDHromUthinJA5g2K(zMa>5SS|1Ctg{=Nx~HP@g?#n$bOr z(X74aGQr^Twg2Nq9yCa0L@Xag9Fw0=wJTUD~`8E z8*qPiv8IDd=$$HGDi$`$9^&w8bOld{yum~Ar3AO&6M^A666?eiBDduJv5{#>oo`p) zw&mhm4)UL+L8Sk|`Y4(>xmY_3xi~ugj}k;Cf(J^F0RgPn$4`N(+rPM$A({=r`sdHT zfRxbK-80f#docx)%}jVgtuUl8~6 zJXx?;oNFH*#5;w3lw*DWLS9ScP?1nr-h?%&gU|X=&uM`nCgFv=A zM-@l{`QWOSp)lGGMpH|;tSsc2;v})%I)5SpGh>}q~8$-hwYD`vot(ERRZI>k#+_DWo=k7JIe|0x3@*BMR^ zOEbg9kr}{h?T`hmZ5ITjebr};ajf4H1zo2;LQ4%iAT^SSt){MFLZZB)pPf8c2HVDY zwHO$EOnF=@xq<#K)f3mFcJx0~Pig;E_4J>LM*r8j_(!GlzY#;lM(NwT;$#a)%T$yC@~m9+)s?+uovigXa8Tb17-c_BH=oo_%U}=KQwV zIf;~jdMeF#c-4KJlX{$WpOxAB`Ff;Am{G!6nAu`(X|v&w8NgL5Q*8iUQ|&a$v}M-O zY~#pK%f&4bH9to6fu+ObQdwSY-MtUXCgC8u%6Eb<0V(<$H&lDJ&)>+s*wl7lUdyw!WXXQ2MH;#l zSB@7Mr%KSf5Nx6@BZ`Lu4G1$}C7%|o{?r&`++-|tr|nHIX=F|);N=`Go84l;7HzF4 ztss7nxu_`gYqq@}T$>Wnto6|DqVd7;Xf?NY>O2&B)*f7{2sucR1yZ;TGKy66O`Lc8 zQfm7xz6@I%-H<95ZlW)?MuVC@e}t@`|APzZM}^A~aoC&_3DC*br=0zK+Lh&inh=4B z^TFV6ddx>It$HmQ>$93G&tD8FmAEppTc`;-Qc{f1zGU*_50=0DbiK6P_NE)PMXe#5 z8L2~|-Hu+BrlJS^qidnGKmuY3_}s-c5eMeD5C_VOa`M$ zCuUU>TL7)}=`UGJL1D-^mmKrK6noc_%j7O*qxgurDU?F!OJoRuV_&VjWX>3LCwa|! z;Um8WT$P^S^5`dR@=bZo)eZ(Aw1_WaV8%i6N-pO0dPVuiI;RzpQDmg{AZdRyfC$$B zg8s$%!|Yw!KX=zY)r#`4nG7q%?hg}DwT0cHk#?9d{>PRFHko|&)L28mu$r1{4egvn z%_>8Nt#qv-BVk{wBxcrNw>Fo8317KeZCM=))zGAm%Fs61EO8Z zTTjA)beN>2=VfYm{-x?h4M}Tsd$|WN^$GIMuws*7`W5xCXc;;6!Sahi2RB&b&{={qi z^tbd9zf!Ns#9_QsgZwb)-d~lLCK#wElqB`C2FoYdBkV$M^3k2*9+={0D8HcE%d6hc&jUFir!}-OF56~#C+^-e$?Im7GWHtk3rV`Vca}lk zrlL-28Vwfj^j`?#y^Ox}P$>p#&|2WN#=~;>r1TEO;vm@|Ml>#X|HM52SfgsfE-yY-S@e0#q;%&hkw zerv|wTtT|Ggs?)sVB3d>ydM_+ZGP6CAd70y%W6_TPK`b&-@DGU6#6V}OvvJ{GWVZp zdaE-QIH^;dc|dlWphy<)BW&+sv zzp~0(v;|0E;;YmN1@~~PSd}frgAaB4EelX&Xe>yshf?Z z-FyS?T+~99w&xK04zp8%(WV_E3s>AtZi}a)NOrjH33gTa;KT&aP3-6}SRrzxJyHNA zmiHlPx?;L}uOZi(I=IXDH{@o7HVaKSq^`7sJ=QH>o-Jj|&TYeW2mmzUqMWT;oWVA_ zP^AUOI#H?jU}WjRZtQ(P0et24LM&?5;4IpHg`AarB6xnOBv(Ar;#3(kFn#zxR8yRquB#Kp8Gzu~K0Y|Z% z6*&3{LbNsHE-i{^!95>UXPq8aU+xy($M$~TCI)RWt!_T3PJDoYF-Zdu+=7h%J1y=} zMX^6`RVkox1ze)k}$3YFE!%jAQsrcR!d0)%{H-P(^FPSsWmFkV2@JFw@442wlJBE63nv*tRXSmtL99F#Hg--sKmCdc%Q-BB+0{ zMU~C^Z3~nD9FzNzlfV8v@kE3BKs^75McxlEKD~ z!5H&-@=tu+#?}VR{e)7d!sWlK0~DvHiU{1=#I+CQ(Fooy~Ic zK;EU2@J6%w{c}8WfVl8e^tXPj`um*!|EGxm>x}=41|+LOsw=Oee$qAajDU0J{Gz5M zDg#c!*~Aw$V#X0+md(SEp*pzvHNOYj;}Ix@v{>XS(NSc9xj3XgOikNQ9K$I;Zm6c! zS>mSX*zSok6RJ2zjb4Q}WC&E_qM;L{DOpDPwAwj$zv^ z{vZ>Y*RsCto6d{jDoV)ICvPudbF$q`!rBteC>FyiRHJOb`S2RP=)%K;h8Pn)Up>d6^?3!*VAgb^ ztn@6bB%cGT>fmBJIR6V zmE)WX11&jb9wtpx_}Y>>GpQEV$gL(SWdC*~Tsrz1@y?K!vdca{p`kL=b4=@T!X_!a zBn+1!l_5!XH_tC1a2?=C77_gCo|I8xg|rY2b`!Ni%hqlz%<4dpc(^j{VNyMcL|5{! zA_fyfBzj)>07EB{az_;HbdyXIv1b{BxA_;k@C59z!i&t`RStCeV}0LKOf zQ%kJ0@@cra^6LI=1x~npQ$?`4xs~!kx1J@qMC5AH)9XRy$$|KpPD6N=9*pxY^+>dk zsy5SY>mj6W6hABN^W7QS{TbUn8f_Dz!6qqF)|++fuwkMUy;jfpi9rS0*&=W|Gx3d! zXZ$gG5#^;bpAan4F|T_SS@W!$gWpjb?Pk{iw;I$ua4kSlm~G2#t)wW#WViXKY6c3& z*_`Y6$!=nG9(H?S#Y-U zy52@>D#oiJ9c?$d*s^VCzU|>%yXAxM?d>!JOProIw3t&IRsMQeswoA()YlYhk8}2` z?vVDdPrvjHF_J^C(H%?G%sH}jL_DuS`l7|;H40w%koQU-_9W8zNoOH?6zyiK)3;-? z#2D+p&HV*A94nQCMo`ASYCgiEAtXM^q9r6g(xNFOm#O*c3!^5+S_?*u%2J-%Bg#^5 zK~dOJoYX|C2{B`1jYVW8(v3x>CWl%J3>ZICoCQVmNnppw8;Z3PJ2s3C z!V@RoHLMQ8lOjJf%nr(xAm2Ca4$_lMn;8a!?2V@njD#k6mmT>*zDMxspJ8cI6<8Bf z^(U-GW7>hL_sAo2cp%?gYb?y(R;~n`P{(sj8bCa|mNqvn9=n1TF4i`3rE3#hGdhJ} zhxw`fb4uR*Z-;zs_bS&L$c^mXd53A(X!e)dKI{;ZsJa$TxaFkP7z27)XIx{~FE=#) zGy|iOXbo0MR@05Lb@t^EY%C|6sYZv4=vP*>HFa~N_~=EOtp50_#Y!0R;P)M(eWV42 zD5Se5xuFQi*I2gjc8a9j(XQighWB*QR&^zDKVG!8w?`C;+{X%wBcU?RSmv5sR@pDQ z@9sfp6$(Tv_7TUwwI%CXG}7sMxi#%y;?J(?g|+xIz~zi z+yg}d)qN;LYt?mRz0{%{sFm6VX-W=ECs+q}f^<^E>J*8yKP3nkorTwZPQH zixG6?sIreJgyHgotXxXw3YBs9IhD}uudL|>*rx;72L;(DTa3h=cNp)=Frmlq z{+2zL72o*Ihw7r0I9-+UPMKA|0A**0ww}>A+r~A}M>g*cE)~nZ2RdgL9rae}q0;r* zUS3=DzG(Y*N4ya(1jG>I!hmK=aHBwUB)GF9IFsFqT$LG!yJYCh)zD zpKop;&EOM5&on|g*~8>=MgjwJoGR!b-o7`dV=48gkNVub?c-tqFX4$9_t`P1kMi8C z)EPP`5B>={YU>+GKRnc@$#9{s%8gKfpG^Fc8t66pJCPjKl=rq>K1If*T!_!8T|O1YfA#Tz|xjk8)%KiL~Ss)#qO{_l@E z5~@FSZx)4K4lJg4STaV?Jndf2<3!jKx3i!;?J`bywWO}6NYAcp9(peFTaSD_)o=@C z`2?=VITpIav+psxNop6Z?!Y3_(MhV}CieRHhCjsVh^p|;9bI?zK#ITqso(|A%NqN7cgt3jl(SkJ)2}SUiKtZHTw|#Zd^| z1Drmo8-DY2wj$M*+yLQ9Ud)$EGcdg}rXQbw0?~_v(to#v7-&<}bVVm|G}5?edl(*R z?6&D%u?|fH2#e4DW$FeP)0#>{1&Yh$=A zI1V4pV?&J3xM$w)7qR2yg+S;n&qL+>0)dv)G7k+y@FNGY>H6meAbhmjm3}Yp;`{y2 zE-3H+bpwBWo%hXN8H{eSYIXWEg9r%;{Ap19(P-pqaF6-~~_E@J`9;U{R$G@X;Kv?b*H&ZIG zl}DbwLJrs3nl5S%l@lL%&3N`M9tiAkYS1e4))Kyb-TZI0Hpl9Y$zVqAfMg$3ENOS^nWmctt|-v?C8Z~~7&6*)KWtM2&2vU%KU$xG+7P=aky{w48xe%(w*~w#ms5 zpAd=roFL0yn`jQxM~yPW`9}k@S)>qSZ7D=(=ME`3xRHV@v}?G3o@nge-EPf{|=85E@)2 z8;#RY1dmaX-{AWR)p3jN3R#Do8maOphRu_O(t0V$6be8%ZL(DhnMdMC=Nldh$@qfE zz{p|Z3$Q|XK&lrNIQ-;_wVWS8ms3CQoHC%_4_84Xw4Xr$h`AIdEbjqb}?SI-+vT3l1 zlpSrhs*F>aT&5>*NyK_Kg8k`er_oE?Sae-nCX?nz=m}w(U21F`|F&1#-r`Jdb0d+L zm;p%LuuV3UV2j16TvXb+Zdd3{oavh^S=DrK`>0zmk{*78o{iGMG&pnx8Y6Sw(hljw$0!>Au``KISK$bxU~LJ#$!p{__^h9UYWJ4#+p0(w||Sj zHg`!TB+OJDF807@C^K$=X8(wR|Hx%y{Z=3~-ZV_54a=R#mSiCvNMd#wRsp|^0v}L}v*yE2Or;sytU)B1Aqu-c*Wms9XfnaYoFLFQ9 zzR>e;sWd5=nKFnzz|B83to>vPiG#9VLPp&4epQ<1w)=F>; z=#mch8ro}1N`3=01Y7#yVpcft!`8kBt(G6Lk#XUb4^w?(c48bueyi#%U?j6{Er z0*#_i)_ND(TVicy(L%~yw9QXTh&zrtQ5bccUVD(zN2I?7__9C|Ga53(WRFjjj)z8} zDtv3~pN(fz2(GFOz5`Bp|242m`=5Zz&dAEdS=7MjyXmIKzkmK6d-_)j+Lt!mx&btC zgs>P2OaL-m#=Bn?q73ju1{RW-3e7q)a~czEb*rtj-j(x%;IcMvN;#d==EK2@%W3xGJXg;ToIVsvNSUo-Ji}H~MTj-GOhSU~&{!fBcYGy+ zT%+SwN620uCZFfFJWW}oI)ggt*?4?^*8p%{oLi@Y0fvq$Q(wd6UeK5c3=?p$7aZGf z^-c7JsGoa)6j6F8wQR&-QVTf1m9`X@4mlI-!d_h0YHL|RloAGDMx}xuvZLx68?w-#hG{~Svaw@f6oI|N z5cy^84~!cKtskBkN%>UVbP#G z;yfNgxa_vM22$Nz(KTTglaRnBArbf!-Yuz-A$6E^_a-{%53hmgcbC{vwvdGt{#5qr z3gi}dz!1zrsRCbn`3Y5{XvJfFSS^XoYR>yuc!5$fR0!d3u)p=rVa*7t#ki~cJ=T?a zPPy|)I~T6<%Pa7T=>-RQy1bIDT1_0(DT4I)Ja)2yV2#EET{~6SMTr^3YikX=gft1a zI=p!#!|n-}0;)510NgY{4~KlVpN1aqO^e-xt#dMjxCHc=ogc zcb;9J3Q#OTg0CigVv5Z>bo*_bHfNvt1qbZwOYSZlLpvUB>}VG_yPX~G{s2|fb#1q> zJyq7tC)jlgnJ(whCNLUpSKk8OA#YIQ5-?sI(>x^m4HyBOl1R*xHTy9IwfLx*=2H-? z0hkf!F@9q!O zP4_z{;E=EdNKBA`lvo3~awE&ah;ShiCZmKtY6M+t$tpwEiGlQRTHlD5wY5}!6|EHA zORZ1fPsPIHt@IE<5vhB|=MCrStz*EismVWnpHDx2YkN#Enyogf^gC^2OlGS;stne7 zmOYdKYMYu}>&pU|U^`~?&r93vmXv;S=-)(?6Zbe=QJ%Fy8bB7_Kf}<#rrv+ad4=Xy z@1-AZLYTLBK?sT>Sv2IX!&j#O4x3$y)9CzkX%C}d zQ*urtx-`Rv8kP;|LQ&u00c-NmaqLpPKb-Ck)8`YNnPM9$KvZ`3|dOAU>*_QX(x^oz(Pe*IbAF2La^fS9YWKunqW3}n8`@_~M7guyc z>+V`eAK|m2YpcsR%R07q?2R;Fo4}w>X&SjO243x~@8Sa|0rG$;U%s$&J*RJv)keTF1lxpFNZ${$SIE7b!h0I55hvA*Dvv=ZpmpP-o>cd-x z9gfj8kGG84eASI<{uGl?kkFesjG^dFA{!+jP{(rTP`X;9O0o6HAKCDCm*!fbrD?+x zgB1T#rL_<&DW(liFLPk@9a=|YlUpF$GO*@Rp?USH;W7m1rgbdT)3!POw3YePvL0|Ej+ z1~D@0qs?v?I1)qzTokt|y3wFN1)(7nrxc~i+WigiAMl5nCO)i4Fhjxw4xc849Hi5_ z3@K;G`GgfeP4|PzhJ@l%FvET~@aNCxG}y&4kg{w)urMf?`A3aS0EhVswryUFP5UMs+-V9p2V@H$={8QoREIp*V(T%!mqxXXI~= zW!N_Kd4SssZ^n!ON7>%>p>6m>Na-H0F|!WeZQppR9fTl- zq#B%Oln_o(GXQ_e9?woN34aL><**@B)Cb7&C50hKtdvjuz@mNz?wq7Ok_v%!qTH)R zEjUR&iw&*`VwKf$KVgn&VC~K(TV2U%KtE+ArJG%0WQvU+`89x&OO*bc$wJlod+QhN zXT-y_$Bo|9i=r|83vRu74~c$K(!`>9yY&KN9_DVwgouT5 zPaDq96P@N)7awn*pA^5TOt7w0tqTY28n-AHE8YOvlxo&$eJl0zi_(KGP0oMZ>7b$v z$?J`;GNIO8q@gw~)zF#0^wV@?nMJ3n6A=wseDye{$Y6VuWvSmI3~#6lv4pKPMYcy2 zZ=NQtsEd_r%FJEx!St$+xj4d#rI1#1#ybfCTQk9oX=4Wua1fS^f5ti%;X-oV)ot4B z*W}8l7;z)@EyE+M!$NjNQiCX6>DN?;jZUHlr(s=wSr1dQOL~KLLVL|fEQ#hnBEUM= zvPkDE((n|Td|25PPt(h-n{@&@DwbYRh;cw$3JJs3S-FNQ;xy+(inO*ev z9OwY%H^Y0LXwOU|<$O6-(Xofz1noRxXvik~nMi1c99|{Dj`@ygwssGa!Dr&JstxV4 zNfBWDo;zevKAup7m-+8!{o$PNPgXlh}h1indD;OZ9cObUzhp2{#!` zTT|^331PiUJXVf!&kWl`kq~%z7dWkceURiu2$ebGWgBRaxW&eOC84)<=YFB`>4!6Q z6qrkPM8^37aqxYjzV2y~o#Ai|Wh=k5Y`M#SMF7gm`*hEGw&!1G6V=mx|M~lym6_Wi zXgAQ0HWhJyDIO_h{lqEHG*KonFRE-ERJBsJ+s z5Ft$hVPZgmsZbHP=AzDKg+bd9^f9=1QR~0i>wed^1ihRpoztFb+4A_N zMu~=r_nZ4A-L|?%V+l{J9q>Q5@*VRQ7k@K^>py{LJihU45Z%2p;$Y=WIKOuhUQmoD zqLaX$+XX}y+Wm@R52hY_%qtWJ-&ONO+qPvj8$|BXk~OS|dO9>Stnn8y4ah*;>ZaWS z7WxlmijTkNZ}=j1=FZKE+hz(!nVHeeu93M9b_&rOP|w`*0|rUaz*5|HLenI{hTz;H zOHUx%hM06XznCrw@Oa#0SBS4HFncLi6Z4-07(1w+i7Gi=KGh~M7jCTtJjeGHRobO4 zt*%T=aNXHVn50@?JLEzlmo1ZqGtS#@x%*$>@ZF=yMcQmwT{nh7bJ=CAZY4O7cb^j$ zas|;&C(cKn-6FXgwyGv_s#XEGxx%w27HVR8!A1K>A)@vPdulg;4>%5;?bY*!*sPo1 z1fFw_2H*M&5%q^r!!0Lm{#YKOOE#L5pr-nLuPO25fx3rkb9VAzvfozxr5Po`RJTM> z@rC#6m>?p_ZJ{cIg|3P(5w$W=KDjZwSe0C_QMk$(C{Vt^M`6m9X;yHn0Q|!nr+z2UtICH8{^?W}#NWd8@F-UP_;>#W!?sB9 zbH;hGQSJ#hLyhHa;X!0GkBopP)v7wfpc@|XpFDrC1 z{eu#r11;i56(g2tRZVBVZzlT(BqHA&r|C!nTr?e3j*KZ#Ce;{VCirlwK z5%E`ka)TuLABaI=a^MdnBGgF4z;H1KpnYmpV0my^G>1`QxVenQstzrzbAbM?F@5U+ zqWYj1byb`;{43Eb9M|dP{{nE4g{SoK${w-D+sQFfq@USJ>XVcOHO`RQ} z@tUwd_Tg4F~{c;ox$t2kzXI!vDrYY&5r#_A=f`DBLwgWN;hca3c}-7C_(9q_jdX%}>x#nNW5A!cQQWI`P!%RgpM{3)qD zsC5MEX?wLP`85^#?TgHYR55NN4nXG<(sCSwP6tC62ZjnPepf>Kd!r5$(Ze*BrEyEmTsJpp`-{7uux9>6`L&Az z+oeD`PMz4TLzIMi2rMO#h)EAhjXeap%ZTr1+~Exj0Aw$<{f<_4M8Pxg!jZkEd`1>U zHh&Cx!TWL2-eA@6Wd1X5Ouk!`+xwAhXi76A33B=5nLBq=klc5SE3_7_PY%FppixR!qmdCVu52 zm5C4=H0;}FVMogA&5;oC5&fO#$MtD=J6!YfI@xV$wop@MGQX9Bfkdr&l9uzOPx>Vy zs>)L4a17}OAa@Hr((9*v>?bYj=brbC{DO2WL zy*b+fm1t*HtZgK8Q)k}@jUhn(Ga9;E=oMfmvpZ>}wG!j<)*3MoPn-dzY=Dq@Kj5$1j6Zj{dvsynP$m|8waf{s*A>FL)_s zXJ-GuX9AkaC_;!=y@D;EPLz;a20*5r9szj~&=O>5T(H5a{9HC6rUuN36H~-5^FB8} zUh-+Z%~F9@DKBK){eJmuu6H(ee|>y_0}&X8_ax2vtE=ZivBKc=-6xxE{T0hbJB%L# zA!2k9o-Uy%f$hld|F)x{-5_Cfz^b>{1bee+)aucJL3v4G&^J|$I%3x73PCM21fFje z{F=(-34>ZL&1KrX_=187_-^Z3Zxh)W6K*}M6b*r~cb92>O;y(|WJ)#dOzylJYMnj{ zp-B(s2k8W6fgGwdy&G&L4rwN8dO;jYnW-&e>kMP@LR{O7cx0N8r$E+lqI(;j5HNj{ zoX38zdN?K98I^<_?VGU{Rq{Pc3YE)Vlupp34#x5cA5?Nwv)$djt=FQx!APXRM}9TJ}tt_1d{!l z*IsJpZO)I@QiqEG!)k&?E@Jnh>Ey1@6cUPtFR2#&+%eVPmV<%z7gR(X@kMmnldep+ z957#j}7a{q;dS|bUbUv5PTd#?1GwJq7qidz>}Iv!LO!K@N?oBV62*H(GWol6JP~55rn;K z#7UsJe(weD91K2C#xTkG{Wu*M<|N^eb;4(RMjydSoDs^NuyX^}L6(#ucA|AFT7I*hah_# z=Uwtd_6D`!w>xxNU|-Zt>r>tTngQH69nW>&i?7LlJsta}#aGqE(#H8e{EoV{GR`uV zZwx(T5MzX`P>o{e4EYd9K6zI|S3DuD@!%e^e{J;qju>|jc5bq}I=kC^fgImF>7^_K zi!H^g($55}pJs1Fr?R%fTIO%1ET3Cna}ypJ{O0PAV0D>{`OZ&S_kiao-s|@9?!WDS zA$t@*baKWU&=XDP-O%YQw<*c*i^vi&@bWD}3BmG~A2Yq`N>b4iQSO&bx1f3%5Z%Bb z7SjdiE%Qw{ML_;`iLfBC5}}F%O@aWMkJf-cng6laOA;(M2BelN$CxIegLA)C6~UWw z*m}LAo^N!emSGMCGzhPViTuKvc4Cck<0aW?&ww_J?P1AmW+s!Mr+!TnjJo5A7DW^? z$HenUVLCmmqeTOQf4)TB@N7PVRlVru8=d~t+Wt(qz`X~(Ip7Lq7wJ_t?uVu|ISgk_P(o{b+!@uY? zi(-_BR*97ljU)HOmDv#m{SNN2t3HA7A?K2COS==)9kK6Z?3U2p&9%1YiO_{uPeq>b=(Hz*UxhFd^5pC zsqj;S-4!QkEsjFAeqC~7>12rtMSF8-1e>cEb+w~H*O*E{_a@W|)j#9)bvC2CNHke% znm1SLRZ||2$&h0$NJDZPMmWvQ_;tZiY2X1X05<8ldV$J>Jgt=UC= zhS<}?Gj1K{L_QioIU^d4(@+hZ>!F(_d}EQi2v5TSxjeH^9LqD0K({hFcJx;e1E1Ajn_obD zf0U951a?=TwwG5T4IsTmERIKFu|GmPHD8;i8?i#YFswOy5LvU1oT0y+@v)OFPL9sn zA2POfy;t^!9HFOoJ>Rwh0#EXjB6o;dNXUKTw-4(FfrIlkQmX8c$f$v)mpdUp5D zdV7T_PbC09$#@C6DhFC>-yRO~qpae6M=bsO0@_h=_YTb6EqFF|RsXk}q$WiDZ@_41 z+8Z-^7=A~nB(c|xv(D455;6J>{?%LhY4_%^ik$ip&WYFMPe}WcjTx2dyXxmzwyP~b z<>uen-O!e&Lvy>C=Nly8JE!Hq5o6ZyVNS}m?mqf$W8dmBF>Mz0kH0*4&MZ74SHPA> z7O3qGfO1$zzu;|bW6lsqSi=O0d|U=&boCr(9fR$zz~x)`qZ{ojpPqVeje=Vc{*Zxh zwax5kZu*;E!9d6Ow&DTR?(v(bD}w~g*4A)R(n7_J4h0~R9&paayX?NRDoi7utUVqy zJ=~hQu~yuIRzb4N7OQKmQA)A=m+qi#&=KvuRDQq8sk>iUlSJKqF}+wJg0DroRNkv# zAq8bt4?*ZF-7Xf!{H=X7IQIntWx|VmAiwi@CL>H8N+J9DE$mCcYD_Yy_EHpcg|rVg zevPmXpOsIXrq)ls;a6}I4BN?1WQQG$s2yGC&f&f{vdB+$58!UIg6>|K7d#^GRM8hc zw634YeuOW6K~g>24qrmhcT+hqg@5R14uwziqka^Q>9s3exxh5K(Hk?0>l;(uCO z{%4W=zw$rj#UW1r-||0e7V`EcK6w8f|LOn#jQ(_kFcXKsFG1#uqa^{g_p*Xg8K`DW zjrZ3SnNN)Or{U~wpyXPlW1&cnj`t7u4+aLq)WpPE!Tj#jgMcR-9q57n_w$VHj4}9s z|J(TQ?>~cH)_-~)OJ_?X8&hFdGc!{sQxhpW2Uizm7bjCg+yBJ@wl>QD!U4Z*DTaWN zTZqChGp3guG5vez=>3yOgO_@xG(ez&ss?K91A1$te@#m8xK_}d`(6x7FH18DhN+D= z1lwl6VA6qDCO#QsuQv#6h7Rx-{Ib%Ydn%VnLKI=e}e59dJ(Y zah%-_)U>M%l3Dk9d!*B35OW;eckALzoXL^#LpgZCV(o-BCK}6=1Z(mj;^=oe#~unk zq(7R(KE>W-sm*-{RI%VmKZjj{H<%CK?3Ts!UqJt7J2wCsQIR4?$l$f7>#xQ2eCUrh zZZ8Cci^~(Vo2-dpXD$+|oMCjw74jW?RbMdNP;PLYQrS69G6h4E6AjnY%u*;4ZPxeb zeX)E4X>Fsl_oiZIs(RfV{*IDEi~XG6EE}9BB5-P6Pzukzkz~mZ2FVEgDx-Rxzs>Na z(7@P-{|X>OZN`s5ddR%|P@2YR7)&p4!f9mLXg*iz8%Zy<846?rk%^McP2=GHnF)bs zy=$>wgK%E6B_oLAqX8Wo^n_XL6yg{~Dqa40n>bcON`;F@Z@Ws_>=P7Z;-jIq)|7rQ z`p6e_-7g^{)8sU7!JWxjL>`Nw>?vg|2|R&mb`Mkx>#QGcfwMAv${U|OGKf-yK# z!_0lGpg;TqYJ9V+f^D!VC^zO$4ATe~(?lN? zxU}1WT7ZY$AKvVqIt^;$2XqQ?tlc?DIoiyy;vf63Nj}XGou(B*$9N;?_fW>})V2n2 zt~s^%UNb-(+Wy4bxFtK@haJz@n&2vb*aZ2~9nM-Oyp(Evs&)X_i-4VVYlk}o4^k(X z#`q$fl1Q*JHXSjtbtwyf9yE@b8+LV0$An7=PO}M+AcmuoNl_EQ+p;o9j z*)}|ojVMAcyQ~swsknWyKsjDQAQ)xOkh$C|2#(1jz_=kYlflGma=c!Em#TasryK6R z{@w4oyh}r&OWMfndLGa3kMIcf{~Pz)sj7WCBkZ zJ?U=SgoRDvcH7)~G2`MX=)WmDaxM)P{xCOZ8Qkxr4{GXyu3X!$_*Y)be7fx=-@e3j zZLo*vPQ-})NCme+gV6-ZZ>&o&#qQWdv!}f%^EWlW2$Jo@mYpXUcT~*=x#k|RT{@=r zyL%6KVk=vItLcdH(33>au>MLu-yY!H5{6zrIijI;O@w__H{7%K0M;Lle1YJPwBMuM z8p61>74zgd9h-SmUJ*k|XkmUmu30Dk$`bo)rRA*^Pq42O#%HUC>7l3s9wj6}XxW_iM zfY`W$xpE|4%uU$F+)q^RA&YUBf0(_T>CUeZE-lO5gXX2?ef`EhFbVr5KAH~NX2kK8f%^g^|3z4d6kx{rJK*xp60^qu zJE>p#w_EY^tB2-=qU*OG(%gHC=(_ri{T$ci#>;O{roi(DFKy17U%9(o4!gyD(a#>; zpGqoahypTXx_d(K$kmxV)+$#X4%xl*(M&m}z`Q$b3WX2P-_r%iMa&WnTMUmq+$*y}d%W1n6jCC&f}3RmK9G*4F(f(OKWLRL-O2&l4aHSf0nAK{)jw!X@2rj;|F*zv2NlK&YW2(F1 zrPt!sb~p2&Bk$mFBw&q@_$G{8+qOjGz)N0{tB`uuM$>up;C1PPN7bf2-7&fPz_{RB zL9h#sQMXcia^#ZUyoZGKNsIw z+$1}-@y8FNT~s6*gixTC5U?xAq3nR*M?F-d^^hxdad=(oi*ss=&WK?-$tU{es0Uq` z*reU-Ch@^B(-?P0rae`B-n>p4h7~4CU zGJM}g$koNd)XwF9-KuO{%`NTZ4DAffzndNu44s|b?VU{i@20HD3c4~N-?^K{XJzS{ zPeMP@L{DTu7nP-JL<0;gs5@iV8=__F*?FuVm%UDYJmlxC()FnX935^sPjB>dJ%8>$ z!u3!!L2U@WyWj>5E%W*$Ex@oAC!(B*9|34cc+Es}+L-Tx+l(S!bqHKEG5NvYmL83! zfQc+vA4B`hTLk1WdvF1pRE=f@$Re^$NxN?` zo*U8xUjjLSxI(Ay(gCnIv4=3dhOYcVw%^9cu8bwi5Pa)b(`jK*aSiL;cKZC@J|C`w z$UISeJkI}LgZDq+dQsg{8)q5Kmq9X$^gys?Ut=Z4G?Ub* zey=jxpA!O$F$NJ6tV#}tIShCR7Tc2*WS>*+*+uHy&N6fGRFA`UZLMH%Mf1W=KC{R> z^J={MB$VHB(_LH`l4xV*NaXz{r}bM}HO2SN^<3zu=LOtD|DkFSY8M58;x&iMmUQ4q zhdB>N#@WiUlEpln)KWTRqP)1jsb!@S?LOw{slr4G>3?T@SAe^4@M2M8eUgUELWTBP)ch|@pGbS^6#-t%q12hvOrSujNL=t#Cwn)aQr0nEi;K{Z-d zQx#i`jJyHTtV5tGTq-Dqy{+Za*xdXCsS;vamsDycBu7x_k>AVM9Wg6eLC#i{;SC-E zy7;M=v@ec;TY~72W^AQopzd*Km00O6%{F|*hUUQ>H%)Gca^QHX7*m{7fR!yz8O;#s1ci)n90vsr}Th>Su+P zM^Ra+0^>=Fnl*Is#Xvk=t{>;%ZtEa}LrE(wMp2k|L4BD+$H2WF((`-L%vijDghqoP z9#2VS>|?Ao@-ah?$lnYv=uv`#fc7YeD_(c(31oNia0DIOpzPxV;lQ8_94p9^Iw|m8 z<0kG{Q7=)`k~~-qw&Nh?B(1S)4WQ0VO-^F;S1{028~5x95gms8H73tdj{lsy9Y_fe zW1~ZV=q=}^)rUmAf^=#R?|wmWVRvOHFQ)Ac(R!V)m3fzF&BT_B)04T$8PN>sg39>b zO{A~(;RNfY5dQ5tC%Yc(TjPBgyf_6Q8jzj^b8;994;pG{t5k?Vhn`1@N)hf`@mX4@ zUTGce@{9sz%(KEy6ktSz*37d`yD`AEndwD~p!VN%m&?scFrY2V)ijnep!#kue+s9j zXsOgVg8+`5(4G$`Rd~*bN*f}#y%kMx)GWv{FonUOJcw4CFa7{oSHHmfb`nC$*3@lD zo2hX!+v0k8V-qo3J!eF$@u8@TZ}sZ!achmL;Xt;EW~sbQ75eP0AuXVw77#k0F6_X?Pg-L-YJlCuu;)P? zJHb(mP!BCj3k0S&HMw~{(Y4Hw776J*(c0Jlki1-6spo~Az*ec=D03ol%Y?um5IfHs z3kgfhllJk9WUX5NQ|*TAfr?>i&upA3Riyw7$(b%ai$?hl zWq0c&ZSN=bP=V1)w2KZ+|KHbwGJ=G}jj_n8vU`L=SwEd=qu1ht0s+I5L~70V(4x=q zEXUn@*@#v&^(4MP6x|-+1TLp&McpP|MI2>_I6tJ6MBm4S^_p!ZBfvDMXGYh z1pjV*9i$V`qgtdPZIWMQx-4p7UKY3sI9uP z>^QI3_?@^KlmK#^hjANbH54lDt8dgFj~ixR>K$?`FMO00HA335R6j)TTj!6yj22%h zgkYQel;Fh{WGOjVD)EK0MK$v!P=`P1y|C zQkPcgzUjOjgK&caEfz*~dEu8Xii72i%L8?dnG6_>Uw}yBjz0bJl<#m0t>A5kLpc&d zIJ>=N+hiO-y#EVMu3g_$*a)m$Www}WVE=JTgeqDi|1fQnK*ShUM{fwvuc>l}_pEx0 zuq?5bywT$lI&^1?)_@|2V@(@-%F>l<5BwOCL4JvATzGa#7Rc$GVTxC2v)dwbMb80= zna-{Rm^g;_EH;c>R3asHKO`$8?5s!i-7*G1;FUAL+JWvuCsi@(awQazeV24Ad>-|M zHL~H+b*K5`GVqgR<8#8r@NvliuH-vJi=gw4iEM z1x6IFu_s&MEaF zsRxA(N_^r6!>XUopODM3yET`oNP1n#IuuM|0vGui6pWLq1nhBc5lRht@X!0G(j(K^ zT!qayKwHo&RJp;|*Lzge+o5lJPKg;$?49ktITtWAvC)OB7|}Ea+xSD(#jwDj zsK`>#j%u*fMn-TjLZByE*Qo|{*7;C{sfS?Pf=MmP}=rigX^jO8J!6mx)@uSn*6(s_RkE6!e1S?_NmM%z5r7S7%1E36kPJYoSFne&tU1VKF&_k?bko#_RDVP}}6sG^F^qRR!a z4N^o(T{?GHDY`}7Wy5swGVk!7yu}0tsJ(Sp=kn6Wv-Y{8r`*6c75a49(^Z?zn5>iv z>wWo1GS|7}>xBd^zI6*L$4kUTMivy$~96YlcZ@BBukZuosO-5wm7 zqW$%HkW@QOK6n9zivun#_VUaGRkz^yh8ot?L_fQ~iR@s-mT%hA`M z%Iooyb2+-?&9cnO)1WT-YxX*HC@n4a=}pR-+pnICDAgnbCq(Em6);5Do?t5K2waOY z=tch`C`z?hA$MJ7d3#ScNkN07;W9b}Gqf3bgTEB)VMJ+*FQ^dPmIvWS=x&=D+1dq} z3_J{1B?kI?FSaoc>txIWlbrn|xtR@?rfW8nWOV&zbPAfQ%!33w@Hr<3jbUgARq2#p}Bm!&59181`&mh&g~7LA39*SLFfUR%zmvM zdh01E5a_(cpR}pTYOzzQ1vNv&9&x%0i%)qrl)?a_x7xpYUFnwQ{r4kp>ILl^i@<+~HXjOlpb1sVkO19L5hX(iL z8G|VLhl=a~DOM4JG}%c`Dai<&$Y=8^>%7a8y2UuQ@=r`RG6x@=^j6xuRnN|}*ALYc zc)-i;Nt)6!{`$~cJcFxupa-VDIk_p_WP?@~?A`nwFC}c<=*Ss)(=8GUvqDQcUrg5S zOgy$!ecgu*v9l__t}=J3Q5M)fU+cmXJXMy{rCfc5V1RHRhQm2^x;Heyw1cIbGM8#| zy^yU9RwrZCmUe8eKu2BY4%UhdO*P2?WPp=a!mq=o<`(&J>sZS;Bcm*fG${SgyTnsTq=H z_EgFGVA6L*^km`$QY~4b4o?1*6`i+N(7)^I51lcbkazwaX$mH`ih0r3nIYD3J(`lc z^DfJ}wo-QKHldTcMb=&s!C^v7?ZI;0rz0Cf7XnC5?Af@N56L$NMiUr_C5>&?__gn} zqjK9s@`%^kFow(FYUQS8;*h{SjgyThNbMWqPWI;y3v0?y;;WSNUI}*GfzDY!L%I$W zpEV;v$i3(rzXZdFme;xZOLR|^YZPa``nH7$oVicVNZ#(`5NBPRxSzGsx2{wl^Z|x zXVjdbO(}NHqSRpX@+bK#PD{9CckO(7T#-8pw^-7Mi{y9%q4l>G27Ocv@IM9qOgAGQ zejs2U1!3-%a3ZMJrO*v>)Apn5L}OO$EiAd&War#FWc7i2ra@&h+W` z`Zi{I>Q|rF`jv+NoH_*6a?aOr&L6Qgs7H43tMWW~$7maI2jP7~rL-gay)#XSk+vDC zuzU;UX}r8X`)PDFmbuQ1zDcD~I$cUjv^? zxA6y(!^;9ja6oR}XPOoYG<*+tOy+an`1;=*&X-yJKK^h#=%&z5b_J91IxbH2rh&ge zj@Q*#J(ZrbM1{wkS0`iFkmRJ8cX5Gvq+T9GBy6ad1IOq;!f(OotGI(B9BRnzH-WCU zNZE?Kejq8GMZTfMchjZ11H9M@LXtokMaqtWKyrzTq!l?iOTB>fS43q`VNX%RD;6+9 zBl`KdO}Gk^f-LR*;yGj9+2h?gHB9Z3Q)`Cdj-o~IsL8o7q_*{C@Aa);hi{0Z-|Hd z79UVw5*FgWJW{YZUAI0bfKiy~OkNHSWXk?uZVRKJ8Mm{R@-K~3xAEl}h-j9SWa z!A*B#4KY`IMU}VMrPT9_yhALN<7kT78+o`h-5OO$JEly6p*Yb*8Y0l7`-^3@rW*68 z5szk_nerEUWbRt+p_@1&&|d6X_=H*dg0-(MzOU4}*XC~pxI5B#_guc<-2M&cam4=Y zo4$2rzCvf=%2wOgQ;dBdgytn&yUEdr3?1;|rER+jTN(1Sr+A83ze#IBh>euE4f23} zAE@_`?g#+g!vl0mbUfcSywCuU{Dz&YAmLlBZaT8dKxOy%8m=ADQwSTa2T(rH6*F<4 zkf6g!dVa z*pwz>9~gMbKjICz!^f6(9UiOcBRf}2l=Ei1jBtj9iigw@@o|Qt&lo${U{F>J-v$gY z#KxxOTLV1wwyyP7>Gi#LK^C?Q&l17K{M>!=xNgx2|Mmux#v*nr=GepUExeFA!_(h5 z3H;U9ySfYz|1j|pufV?A&JXwF?z-7;(Ea_=d5gI_%n-8Jwb2DEEv*ac;m6=JCPaBf z;xWRs3z|7ms7ErjM|C6dzIOlb4FPsT5NjI@5K!?qEC0`QEz3V|2)_GUzZrN-7gGg8 zCqr9P7gHx$OJ|q=-5OZCpdMoRnlaF7qR++w5ru0i2-}%38EJ)!_RB5NL)BqMmF}6i z*TJq%(AL-ctCXr*BsW>v-p(m0meMV0MPeXRLpL>I*iN4!c&`b3uK&5b#{XIVtIM7| zbJ9#CW&X)w#OMCyDRSN7+ey8kIsSEAn3Vw2+6TP4ue>T{;{X$jeE%LGk{QJy%kQpM*07 zb4YoD8#*FHUzT7wO$YN}H-JYlXUnAE3tZ^lLEoIYv_rORBhKlyaP9`NS9bP;lyQ(l z5ZW4n9Tp2#wkk()(S%VQ72UI?y1L<9NK z0_XScmbWH$u4TZ3_9AALy&iHFar(n4H*3aSpar21G;ked%ab+3++>FhtW#~E8XuBX z$wJFAh>hlQy;>cNV#dv36=eF+=f!SwbWy{F+mxoVHgp4e9@`Kcy>Sv}7OpG7IsSY~C?c`D+_Omq60e0R45vm&=u<~8e7&p^e5TaEv!S`00)4a1UVZus zkiGt7v)&nd?QW|)qk!9(UR-)|-_i>5r(YZ#M|vjvxFs>W8LSpP6Sac=MxDE|aKR-u zc`Vv0L>I9~TdG-O@+b=+AA$G)R*RJ^+hn1EXSx!#tD`347K~C>y96KU16{sbI*x_U zPR9X^ZbVa^kuhrV9e>pnL{y)BL0t&bwC|Sd9vaY=uK0(}BNXu?ARxHu^rIxFtkeX^ zJx_h)iD_SEHa@1EC2YMWGg#VuHX#LZYEG#`AY(DL{+=U3fJ4kw43ZJrdx!>kANQY+0fkG_ehdM&oeE}&UtZN=SO(gs3gOmws3khg~d1?#clgo+ZQ zc~lXN=<|RI4H6>U9=+aBwqb^AmU5if`ny}%sNgZBd2oR47HT#g!Rfj57|%7hRb34j z=cXdpJ0@E^z}czZu4Ku>KTlBE#i738oN)+zC{;9eWx@n`Zog@0sZn7}GMD6~4$&)& zoI*9To6dn7=KFw9a`hdpA}g;dvqB*~%b>h8U-#QD0e#6ZFvwAE3Mqd^Qz zT6N@%m`n<&&?Z;SGV+#d>@Q_p@2oY1QC;?zJNZZhmg$CmH^`q{W8Ie*k4JN-i1M7X zzqFQ4ypLMEr=jDIHNMP}Ni|!b&t{)d!P1v`8g10%EQx&dH`dua_`?$KteCx1hNYiq zcUvkdv85KJ?F>tqD;3M!B^gDMy)n5cPM2#$lgt2xAH5>iL%{fOq(-ahm7?SEeb05EV)JRsxlbYS4T!> zZbl}>8IIe5ucBlsjCMyAK~1_ptsz;;eRc+eFp`aC_TQFqk1>Qbp}|_qPy>s6oF)$H z0bl7cN$+s#KX#9$cG^;;Xl*U|LeEl~oHe%QmfU7jZS2wfc*qs}zPMOBgqRR~$GgWp zB!ONX=+M{^*(V}8p}Y6(R{Zy!(FoOrJBif;eusW(Y*LXee1QW~2`HU=Lq%F?Z;AJh zTeSUd1Wlg&`@Dm5vjmVJ<=;W+4qNoxcpz^hpZyiiGd^mkyeZ{$)K=B`#QNb{jd$uUw`;?vWEdBc( zd`nmwyepx~aR%aT;O-k=CfVj7N8xjK!;Oh@5D2pDB z9fvMQz6WC0*Ov>#q%F9ij?6O?`RpNT{_^v*XRB*&`|?Dcb9#WpS(*gb{i?q9G=$usbDg;;A4D_mH<7Sg(;cVBAAMdZ*GO^W@6pEqaoIOGF zujMrf^ReE_E&vo8Yb`5^_$zeSbDn`<9^-5 z=|b$ZgdPxDu@IW;L#Jm#+SF;Hh!JYSSCMT48mDEi|;YeINhm}_{p6>A}h85L!@|$EMU-Czj6-0Px-%WT?fW8Po9~9s1 zm2C%U^k+qkv@h^cxxpEOkrx{;{k-W`Y2-xw3-rcoqfr|dHBLSc!sPk?LD@S6_Y!s8 z-aFpOj&0kvZQHh!e{9>f?HxNiwr$(?m-9ZSzB)JOsX7D>*zpfRkt9l=o=$7V{L%w%U!^9=XExf;T zN8F}NomMh=Kjs?r!YvLN9yxybp5r4Mt7)13c`OSv2mc2qaOhO_;V~YI*K*Etd}omr zIPE(9q}w~{4?tpP2}h%qP@yWbj$SWcA%Fn(LJFcHnS;FIkqI|j`I|Gj9blnJwYsT0 zAT`%I)JYKSE`;fT$w$r-bn|!ErhZyJo_&krMAr+B#Wu0pG*M?(lWoyd&mE7&VO8tf z1tWhsaE_8WX?}T|1p<}AkWE!K?JHDOzubXa zURW$`s!<9fFctO6fF_;ooy+oa_R!qYTTFB}rfU0gto!H%p54JJb;z+2C>YjZt}^fC zER&a~h}TVhUROqLL&fiJrmSQ{gVcxswj0y%*|Ilk(-`JjJr`yVDZyK<@!*W*l<)={ z_eeXt`IHv(@c|Q?bXh&HM0P#yVv0f1E~izBNruzoqzt%YMGST{cH4>2djSmg>%A^_ z2i`1@Q18CJaz*-J*Z2#Z°`a63Of)Tq$&LP zu^8Wc(~09fsS6>3g16yVEK6YIjo zp_rX5oH~7nPdS&sd7u8BPhazSKOheJC5Y!ZwRL{cv}EV)d6})p_wfMRi(k~6ACN4C z`lmVZZ&8;%@n0}0(%c;J7__^_vzShWge60GLH%Q+%kmUvW~S866nE;svhY6s%}u~= zvM|8$$^J1F=)eRWNg6xasjLX5O6UAVk6yFnTscU;QIC#oPG|brxCrV@)Y$-L%J{gO z%6_ZiD@lHQn3+&SQI`aubwp9s=GH-QlLkR`GSP&`aY32-WG&(hv-EnqCG8|GI=h1X2 z>L$|}z935XCaiXE`WO#*EHV_&AnB(swjo24%!toAkRC@*@bNq|icWSmlGPM=fNT_9 z9zhX>7EAV%@Yk7L+#UzRgUiPQvDU9vPddut7jyOk(9>ZU!R{5^u@B0WM{Do~S|w?p zyNkNRmP5n~4o0XaHM=TxVbn1dyW`#g5`PCd&8073f0j$rp&NKMQ|0(>NxksdXrh4R!OW{mpC~9Y7Ok4!zF=nCXZ!q;glAD(LN-++?E_ zndDhSiLTz z?fS!#0y!VgF~(QH>e)#@e88pHPC+L18r5i9UWh-FKxxckB>C5wZouhcYU9(9&=~(73zraI)#4F~!$J9br!eCRrbH1_3A<1Uk$x#Vd?|!dqWP9xE z@7j-9 z_G6oGtH6v@!1Ejn+e1Q*j~Q*_8Lk;@mf%aYbi4%%hE|3MHZQqFmu{N@yNc1)hzWZL z;f}sTY<+|X!Gxw0TP5;7)6h#+RONg|>tULlkS{!@t1rCLe^xdYptn8cB*o6NS$dTH z;p6hA#pmFAt@W>sb3z>cbKt^-VZ9AazrnQRoIfDVn|-U#|RfVCg+v&QyOBOH_S`a$be2T7kAuLBZP!BCTvk#dnH& zOVm~dqb$5>oJm&EBXW$B7p7T7gjku6$gM$blxYH`Tk#8t_7n28)A0rKZNr+KmiBlU z7LE4T*`U0MU9fqzGESwc_rxXZ+t45)=}-AD4y^4BBA%h%ciPmrc#5CKOLk)2#=5w0 z3lYz9*t5={s{d1Qjr{gdSuBR^hWib6+XjEV>O4Mtz-XrCrcP_bhs5o?J};&PLh3N7 zGphsE8iR$)KbM#<0JJbKw=~11ob7(^KDF)k5UMtJT|Kw`g$whAW((;HuB&Xd0_$5G zGU6$!&MRdByuEj|bu=pBM0dS_j97u{*gD48Y^SM-jn&+q z?$2L!5yQ}O+N-RbHODQ*H@s^hr;-NPHRvkKKdyPL8m0Y`>#?mNf#Dph7wxyrDJ$An zfAAstrfIk~1E*3O>&q)7exWP^Hsr1~Y^IdOdV$tSIEn0ZnpNz)6}kfq!ERL(vd?KN!w_J|Lc8_gVv2sO@W8 zs1P%;8*7Zw_|Kq$j&yFUN_)yCqGJCdvZJ_?Z|6LMY@~sOxNl$kX+V=g~Mt^NO$Qjt<2Y? z%O%gHQVnk$-eJ54&>+J^;luD&5Q(LF(X2dVat@vO(CfeL@G@GQae77de>@=%7Q2%- zuShD6CqkQ!1C>{OHF4`+%czzX+KKBjv^0le0^WhTGO9LL?vfmf_8oJ`EaRwY`L1#^ zwTMEZG@u$7O|Z_DWigQSRdG#17!K|8#YWP}s4;OAG`Ixs9DX(6^kC|xPJv;%hKQN! zg(K3x`$@FHfu%<4dKCp38cxFr(;s^w?zZFCIfk0%)QsO+)6$?8yvuBGrdcHqodb9KN|l_Mrz~AO{2Ukym$-?Ly@TZsKGY?VvFejCr66 zhqQoCdBytt^puhoe^8JY z?q-^i%N|UW_ku-3#SBohLDIFH@iQ;@RRvV$Ce6&o<&!8V!WqbyFg&7-XKEZLv6 zXL4BnE7z$FRSR*X!#9N!U3Hz@((XKBusS6Enm~=zr2) zbJuK7EZ_aLa(8A=j%*$Y)}Igd)vV6mQ14>nni`mPTINg>qU;)HikaG+YGL-e{GKk$ zofc2_YWO8yRoXF%cUudPCr#vH2`zU_+oJR|%=VY3UO7s|&20DJ49NHJ9oa?*leWAQ zE5!O2|0Kzj5!jGsitWV)J7zkDv$9N&vlz7Y@3K!`Oo?~~H>pV`1CL)ej|2YlG=hWN z75xm>;yBMs9>0k}6G~&e<0C)jPT$kI)!Po$9ton9FJU_^6%75hN z(~A%cB89fVs+Y1db5?^-3~n^R3|Qj?v9SV8{@NLgx)&kaULr@L;UeIIlX(XG-Q2GdWTJ$RI{uy1_fu9Mh z*?XXl6T__U^;_z8W>C5uYr(WR6IG!)5_OJ3Iy6QY6Jn9!5bkPL0A}a>Yoo%xm1<`g zGo#LcW<1kUKErgv^v-0qd;u8t{PzI+qsTgo&N8RQj zMfA+Aq9$o1hfS|CmRfdj2COE~UDdPeBPgbt(as)9`Q{*546SS_T^oH1QyOU$dq&_? zknC?T)`gHD-*x`GQII2RI4=FUTWYrI0#>xwpQO>cPy5tB`qlooj9)|yl;jO2-vB>#c<0=oHC@8=(nWcpvjKE0q?(U7ItkT7pFJh7;@g&k;(b1 z=a31}XCU8EMjQQ*H?g{D@RxeP+}I)%TBJj$o8Q>Gjz(WpOtx3Po?r$c228*x3ar~< zkPvGhD&*9E51DBe8PXMkuwEbElJ525P99(N>W|Qkk%I`c=MA-Vzlhrt0Aej92`YZv zd$z_yz55|}=Cm%g#4F4Nv-2MzlM2Ocwr1)-`eWioIeKl~^)y9$+C($?T$w-nm7qr) zaKr&P=4Iu!7B=P8wHDgI6u5kDsGl^w7icrV8qT~rpog#)wJ`ocIR@hF#Y-}&GsU#Z z-;B&7hLTvskGMq6dD~V6| zJc&Fwuq&paeWSDqR>ZW;5G7(ivC31l>7N^GUwf@?5GIdpyhybU*t*W+`g`K?#yP-{ zO&q(ik#gFhno@(K8i-sJp=^1B3TT%M%kL4A;7-^O8aa;m% zq4R-SCBqDF^?P98qZxD={2z}#QsqjcZy0XM)3#{w+t|FHmY39-re|>*>kQ<;8aDmBhN!o)W;_%{0W`&3|ud$`rsaaUPl8} zD=$8?I>G!W0?%au-W(Ho>M1L8^HgnlrS?^c+2!aLC_g-m)>``yRRu)nE85m$%JzY123~cy&BKrxytRFq7m- zm?oG%^@*pQVCA8kuSi|#BECg@Ov%eGL3xP=BK|x9m%4%coqiTuBl?;uZfrPzS0(J= z{FG->f%XHti1LbARd@y>q0QZ=MXu-c(qS>C0v%?yfhyvMogHuMnDA!f$e5AQPw^i7 zBezO@fz4knF^}Mk!@vJ(?CCYLzX9hzDf_&P9EHa2ro%~PocOUiw0l9Zh9vp}J*_Q# zLKmP!jol3x2P%Z8z@#X>9Q9%R~Xt8k}b9GQ0R3@|4t3^%3(HUQ>tMXrCdwplB;$14m0ELs#m*>TVl8 zIT+vjVEQlb^{bUT@cedtc|j#7b;GA2)CliH zP~(I}^z3W)-8v^8<*ji}?Di=A)$tK^;9~}iXruu|fvX7REF>fyu=E&0vIqUf;*+-Y$u6C?*7}y3=@HeJk)lBL3l*(b%Dy&Q0gUcK1I(^@PrtSS zn3RoIE&*=drGtbwsD~2wCY2u~CnMXYL~0#)<{=>#g`kRy6GhRwreyF9rA+Px{j^*8r3^Gk()Nx_jWkx- zm?JEQpn&0p1#i(4g|o0bg^d^SqFI835=Nb!Z%25=2u1tGUzpM84i9hsf=82ZuP$MP z0EeYrS~VXkj$G~}!|RbRqxue@_l~^r7nvBj=HUULp~Z3Bmeb}^U!c))r>gBOpZcX? zpO|noupm(D1rqDyLtvTt|WsP zKN^%o90Kk+(LyoqIp2EM*wHaZFhDEcWy-vP z$JM=WPT_>^x_+y@v+3&C)0Nje8?gbpeEl00a_kIDas3bF9Hbr^0avnX zZ2R_jXdtc^g*s>KvWaXfr2^b? z7q&bEo{bRyuI=oeADvwTX$tqouobhK@qn7Qk4uAQ_(5>Fsb!^qFoea~N8eNwyYW3d(V*B6PhiCiKZB(sL#U5; zqyd6~0Sez^zD~EE)CPIBK(}N?3J?%sFyDQ6VH~eyZd>dDwqJY|BS$UjhP?4P@;2n? zf8IKRbXUAfI3OA*`rothZigFGa`}e`In03AHz&XADZ0^GE$MTfL)OO@P656Db{vQoI}*H;{I(}2JMzclkKkz z*oz$mw(2l)XbNcK%mWcse-P~(>|5;X zl~1zWcS?roq5cKUR&M((yJcO@bz)tY%PVbkK8G7RDcg+hhDj>+VB^@le)z|ww^s74 zhvQt41MTVEuTxpgEJFXBRb%1hYvfBGRulvW+K55&<2Z=xf>BzmWC zU_>K44R|g%F#Ia9u;OA$+0~$joW}ofe-}z%*8X`;|Bj$9WtWVmK6&<3-}}r`xQV(N z%Wpmu`Zjo>I4Xy&&geknEP%-`5o-5yH3V>3n`kt1{%Ii(|63D0|%K8l_Q1 zB(^1{(p4`9=K_PF)%yCTCHS*x<>{F^nOY#D%@J`o3w%%Gq4M8@x@MC;NLj#7N9f*Y z3Aed`Vpjp;AzBco zgEWgS6s+XRPb@ECsGkpm7xR2sf{RBsaxH+DSU~J^t<2TW7Eh@jub8niO0{sRsXur( zt@6?|O)p<0+@E?Xz5{m@eFq5?AfIN#0^-}%Gqi#G;tSR4RS8<&7(1a3bcYUPxb_DM ztb0Us2=3bu?W?3xfb+Gm21!kZr0vAhez%^yGbi$2hJmJ$MX^u$@kH3rWzj1dKJ~v9SW^m6pYj6e7D%6^r%v2VV#(*v7ah}Vs zE3QYGcWt?h47ir7U7-ANRXg|@g+SZHfq5GXei6a%THemdO%*IJ;@)z|oW0-FpuKq| z%QQhQE9z@9-qlx-nf}A=Yl1H~m#>MGAlB2bXe-X&8AL4s75Wh<1S-HYABm7WyQ zNIv$g94hfLUm^pfv`%#7nOt+!2v=bi5rLqDjbtB{3?`!grQHaL^{XUvp~=jEut=~e zuiBP*^zqW+xHms_8srAq=V+dZ}-rJIw=w)PI}bOG`jh+5R)QK(z6 zI|R4r@|ZlKcT!b`fpw@{zU=me+uq_bvsH;^d-Pk>LJAKel6?&QQYy_L=GZ)wb1Zso z_eive;6Gx|vVnsr06!Gy7~!|e)>oaCRj8)YEJF1j5g67^ic4Z}n? zECCn9YI&=C%VZ7?WTTx-$gmk6D*x(J_V_g)Q;Uien#ty29vW?xb@rV$1|d_izJZPB zoXtIj1Wb=}woSOni)Vei19n+Uv-DE`Ml9uB#5-w*-hHd{)l|9mnHZ82Cl^qz^ZtEF z?Q8g}GMAv`y~IJRurYoYSt=#i}<=8b=(hZDPL^#{7HnJ@6PO&N^& z-{*7uGD}{5{wW$|V<>jpWm10e;umeJqT{KwnPsSynK@Y*7#@R=JQS+?`*+X%`R=c0 z{~kVn4KpiOp!g~OJ%no(g(>IZxbW-L^w2huw{1Bloe|OFQ!li(M{-E6$nu$B{ee%g zd+1+tA~Td8(DR*RacuYz4t3jb8-`h5IkrgO;%8kz29p-D-oN>Um7I*Ei~vSD=W}aA zoLFvW4nwUcw-!6MGgfJi|F$f=^f`uP+Yj0th|?xUv{CrcHu-y-0RcdgX{6quXX}_S zZOt{yiP{etWzN^)?FftYF{5)91@3~iXB2TO#nO-~mSnouX{JE~9UJv39O{&%rC)pDSi7d~3> zk^LbZ{?v`Hq!$gMeHabS3CHSyZ6L2q^^`ST_`Qy>J{Q+IyJ@ZX6Z0P3O3L`GXx|GV z$zFf|pRjR$Nn2Ze8^A|K%ETsHtCpcvxj&Io3eOKuGIEvbB3_8LT_Q3Ri!9P!vf7{) zz)48euPfVN#xlUVFrBM`{pdP)w5D`{;eoa-uMcSo4=`{2yIOx!(7Os*5Q~r^y{~%` z{f3>&t7QkAXb^VrZf4uH+DqY$3m#!q-sd_-Do`6G)9i0^#b(YSQ|;j< zOk?F_smtZb^}rid+{bmMyayt>jhGVk37MThcO8W8KBFuWExA3Q^5`eh6aEikGV;Yz z0dw_5#E=CxD=DJM!~YoJX@woX?C&_ zAJr{N{hQ*|5??Wt#*h<{{Y5KJ?AjYXtS?^@=pJ(X zYQ2!QU(%qC7mzClpC~-k2i_zY%or=xoe&obJ>Y>-W7WP^=dsJ8E7ALD9}xB*9O8w_ za9xrdz-xUGy339$wcEYm9|EvIu+5=fpJXLDfjKANmRw)j{3$+vID5DdZ9z8bX2raJ zp^_j+)kLdGLQ|tVo%hHGOXb#V8(`YiWR6Q-Jd>h<63wb(SF}EQx^(@F#eq9>)GclM z8!DW8pO__qso6DBrT5RM%Ym}+)>(ZZtq|b|g`qw8O3#P*b8YSA$TQ~$b~3c3TdW`W zGIbH!rup(m8p9yfUObP1XD``7Kf7^#o=-YFoau|jwhA1ncNaD}CHrO^c&I^KvYG7D zwPiTID_h+il(jUEp4-`_cJS%CV-%aIki%1*^XNAP z8Y+s*>yjrv=qm{@d_bDHIkSDZ@SaxjeJ-VRRMcmP)@4T#=9WhV4@}C~zdUZy4+LUT z1&Kd#oO&N1jTO1tjQoashP~z7$c20Y4;|h3dE|4nW-gWuZT@P2o(@}$wS|*m)46(; zH~He{3ULGFE8rY96F31;OoUIe348&LeUyIx&^V0RWLr6d38QX{vZ_`B(U>?dWJSGU z;4{t%dgfx_w4Xrw$`gEq>cytQs-& zND-JE6-pR;$-wbx9;D(8_9I|wq$fr{qv^ppP;X;tcL{-Z+zN*xub^a*>j8P5YuU4E zo)hXk@ve_7nLPWVk<{q#<#`M%VdzT;krhKbPiWbC24Skhc7x=ASxob52MFNEkzW7) zUw)9>%en;`(}hEfim6O;bq07St`jFXw8o~op5FRiqn{s(DlCk7uFevK5QqyR_GUL_ zI<2_(Ex7~H{s{=D)<5c)7TLJu9P(PqpsbWmUqijC#_giYCm|Vir%8h}7C2?Jplh&M zA%z|W(&{?N%j#YEWzkZ=9sN}CDtD-g2_8Rj)@36EJjjNFv|YCf(YzM^ZhF{wMKdbQ zeI;TzE9^P40??4Rs}|r!v3gLI=QpNq*O~F_e;Nq}+-ye+?uZC5s(iDhN> zvCn08ZAr0&M6XQFs01;4Y_mR2%~l`i8w-|yxfFx0hx1ZvuT+c5cwdci5qm`@`LnB0 zgiKQ}z`bQEPESQVqw&x}iw{YyM=AWm1J@GP+whXs`ypj;bmo zhE->QMbNCRT9%88o!JH81xJ79w;rGGk(ZGu&QhD>_Bu2yFq%}{5bV7AvBq&n)#MTwx*Kd<%*RMf zBqg zu;#_G^PjVSHeWTxU*hsP`{^8Ux6Le%Uso^pY5vK-KK8(n_Lh7sX0r68B#J-g{Nf2` z=8}Ve92aRIRSwM%297XdrOmJIf<1Ts(f*b!eO1}Dhh{vwZl10!aAv1y2qTXj8qM4l zkM8f;53e3ST+TX?=avz7&j~y3SIp^hVa=nkF}E91@!JI!RFdiM%SNt}|aB{+pLLNSaq9xI!C zk;f4$j&d&f+C`D5VWLCQb8oDc*Ty{U?0}dZr8)NkI56GuR1lby)zmg{ubLRP*mcyA zzt*xvVSY<7dzeGi!=n*<8ar%9ZZjFls!P<2$8t;HY*th6plI#Xj~-qV$mcO7PS5_K}~N!l*5Ei#S_sM7I}cTGE@v|Z(C%c;gofu9v#c0J%Q@i&u=CvJ*yd7LV6^D&HHj-C~k zMr?RL?CZXjkB-&R@h()!h;e?s^cV>r%N%E!fEZ znOAzNOZ~FJJU}^22X`L@clUmf@D2P%J|w~1dA;XV)iQ6-rZpaKJTWq}Ocrz*{Ofda zfmlUsWQi9`Ik?tVM)+s&VpZ~0Q9peG5=A5MRDRFFEvuO8%9aUb!EGw^z^Bk`jtrGc*$X+x=S9aa(cEjdsZFk^@P zkP)aGyPSaelCX`I*V%P&*ohQ7whqzf8odz2-ZvyCU>ZJEh|QThGy^t6iY6$f4LaHh zYVARhEtxux;fw;9SzHiV_G76PtHwHEY{w|Col$L1?iSEGA!v_$JF)eMy2`(v?|R_2 zDO5Z4d86sp6FXghp#O~SmiaEaY>f5bh<$V8zT7FaAWPl%1i##CdmyLlb*15%qB?o+ zjPU6-@CY$_FyhVi8B?2c@*?`ox-LQ!XiR;=XV8xldgK{x@R zn#@0H_YUhX*-kj($%#=y0KOw`hm>edn=(cC4)d>tUf6R)UQbxY!z!c>CDTo6`y;)`)vKK2)`l_F*OE2Bdr25J>sg%>G@g>+K_yifz@%?E$w;vf?$W zoGhN*rsS}MO}7rH{dS;Bd)#&7W9={u*u|(nI4g~px7TyCcdCPktprBV2oDNp+I9KJ zrf9A5fz0Kh&9j0P9pB6_ocrCInmL^SgNcQ!L!8^U@YhSm`*l$bltS)8$~&G{ zxgU9L$3d=J!QrEbY&vm!nD61>a#a)o`gX#5fx|7#ghJ@Ucm{rYFqFJ5RGew)-eP!c zU|ZLxo;ttmp1WjUe7H0ktkdsE6tN;vbw;E&1UUFJza z>b5}rI+G6L7{ zxpFJ}QZoMmm!2y(0nrFh{yk7KnLUvQ@Xu`CJejO&ecT+Q6Ds<8He^;_m#C zN_VdaPT9$1yL&Gp8`f#Iq4Dh!nInwtWnoPtRAWQE~^FoMx&`MyqbJm!HN zL5N)1!I=czF5tZ zy9De3He2vIfMct0{-pLGR73~lYm@)FKj0e#^=-Ru7;iT4f#I@9?!>j~6lSWZr@zMA zug!Zz_ATl!d*)%PkK<~;J9qqj-)&(Vwu>Vt+MV>yI27)96L(Ce8~3{#aBjFJ!IL0r z%#PEmcy}C`0HtIdkJ$YrcelNvFKbvB(*_Zk4GM$U&7t_5^QJnAQTKZh@wI zdBmNCB~Pt9+g<9yq*ut=SoN7LuabA>rzKjgBHzBtBXF&%ol~htXyBPQuax(IRpX!z zXX^495qnka9-#dPum*aCaM7E%ql6=?xrH^1+e@a%L79rp|0iV(1QC6(O*ydBD=#pU zL@ruz>ylK(Z-LXYPU=+1BYY{JIaaTLR>eGSP|G<3vpQntiRZ4I;e#?-kxc0?W+iMs zH-PDm`-DWUONgx8VJ?NWOl-joK<>87{pi<+Zo5`d0~W0d=HU+V0DlojrH=0}=bW4| z;?qagK8BAXg5gmkK$6k$cnhAa?%beys}eImct&rpN=hT|2~z-MR{@u-h6C&6nBk#@ zlTRw}^l=7vM$VG14PG84(BrZiKiW{JK$~a8Cpe~5To2$c|}5cSA}VXA7N7~VSi%1 z6br*+MG9}z0c}R6d0mw}jhuyjJ2U*p19P;DGDm-6deu+oldy0%l^k#WN=Zx%tY!@) z@jR10Emx~%puxr!8&kL9iAloTRI)LfOjjh@b113u=$Kh=g$`9XGJEh2&A5_(w0zLb zh_Ts_3MKo-jO&SjWw0cTWShZvWlyIXv)>W=vuS)Ld30zn?0lt7wBb)m33w1ZjRH0#w4D28+#eH|g#$Sz=c#L3+u) z4Y`b`;}1UW!B-l#D{hs3J)z^M@y2`iv96(~c{o3jl!+5}|d6py7RtRUqWE+-z3b zTr0KJ(w-~58tDvml!RJbeqZ3xq9`=>lrYV0_nmsN8~r^E{Zx;yshU*u~ywhZ<9aWZX}LX7T&Bj>sJGS_gjHx*69OO0`Kb4Z3Ga zJrp=BN9eCVoBrcy4UJ+E*#(L*M8#_cXaQxTBRO@n_zQIq-s*7w?=XLXBR;!)p^Nmc z>|ZTUptF~H#B~AJ&o}Np}7z4qn-)i@BMnoQV&L+r9w` z)%LD`Dod4O+hT2|=nu8SwrtrJas^D@W&ZyrLjT=N=Vk6`|N5JF_*2P-=X`~V;B*VO z2L+=St}`;hAsDux^aMUY6E}p!Hzw%KdI~__kQs+E^nTQNgW zfw$^exIVkhoiLmRDG9A7xT<5qtXjHyKROMNDuil6ZI?L5sh5Y0R2&P{X@wp5W75Zz zUY5h(nar{X1(O@8{V1v}6H&+Whj>;yS(K#-`l@t|B#QsF5LBgyZxlo^S83#oW$159 z8_0yt0;h@aIpJcMjTOJV+_d2{+$n@~J(`1Vw`KOas zN@i4`&V*YMOsbU1H&qmBs>sPy_@|VMYL;jCOL#5hr_3x`Vr*8Z&SYDXpr1>x6|S9> zTC#M3{=I9~6uK^h|NL`wpoEg&HMYZV*~~^W%37FU%`}EjVWQYPn~+2wDUx`q!!utu zsq8UdCr%po>e5dbBS7s4iWmO)ClVWBSTvpWP&%xEwk99zfx2>pa=lp2xIME3SwoB5 z(=tB?Cb-MmQX{@eYFg=mnB(n1A^{LSxc=0YwBj#Ww-EX|$u-w-kmzk@34V7^rzQ;Lr)5-}JHUq?a#fT9Ci=|y&NOUr%j59TAeDLnlvn6I>3kgh`Ogy&J^jek?} zThybrJzB#%nrY!Ogim%jCc5~veemMlykbG>LGebAjE2b_<7T|!kulG4w{U_O&xG`q zTuEox@KCleba8n`P|5FVuJrU(-5YperO8wW72471_efyg`O)A~*~+*fUV8=9p`bhxK<2gIakiW1Cd z@Pgkk>sE~HsBUY2t9&}StdkcnZ(`p^S&xA9@{Fu+kb{C|h)h$vBNH>#)6wH`lIuZj zwvM?+%WZ6T6oD3H=;6Tcl$*n&wA&l&Q1xIS9?Kkm2fS}PLY#8a-BA-vz51PW|a+=HV^9^WS zrof64fq$&4eyEQt6nDaB0K;35Vwy?nZePKxVlFVgf+W1WoCKLI~ zEKgvq`B_75Xr5Uw?5(Y;K`>?<+JxF~msiTJa1_N|(M+&G)k`h#uZmTRCUjE>Mvx})CHWmQ)o zXq@F2Exs44jlp=!-5!RSU7R%x46b<9#gFY}_=2JA>`zc8)u(yKNUEyRTJ3Js?;H@G2&sQJlHy6lgv$H)-P)2E3^Qa&ii37gWwjb*gP=|14~J z#GlQNFW7o#cqqOv!Z~+%Xh1AbwJUv!KrDKCRKJObE|hv?Pc0$v$PPaUd!d~>J!p4f zV0!?)JQCVp6z{A?K9;{BZbm#%9zeuzM>`|G@{IJT>(%sB)iR6TO8n3f*f$%XS$V@d zRYQ^?h1vpZ>appAZ9PI&HD!w&Uj*$%QSF;DYYTj}XgQ+xtxkogu*$XNzadiAvA3%g zVzoHLO%k=_TKtoElO0uJk|UMnxRdFI=rDeDP#YLOnt-oT8DUmhN5v*Z-!^p*jQzbc zs9<^wULvpbV^qS=2&&};?xY7#q2rf=7{fhRVR0N=q6d_+kRnJl;8JXwxaS2|>z>Oe z@zw_qp=yLHx?1G3C|oy^(qN^zHjbXFluG#)jOLb9d|?g`-{z7J3s$Pv;cT=+Lo1Ip z&Qt1{ zV;0(#gukJ3s`@4$om4lSw35}x1+ud1YT?+6xg{^GjYd4C&b5lfB{lo46b$B{>FdMC| zjwItBg;SZD7VLhx8~riDmpqzDnY@&q!UrpBa>kZk&Ih-*qSS+=NF_|MNK$N)6Qx_J zQ;^=J8tUaQQvEm14fvN*w~OXxm#Q*pxnhY6cH53ZH1HNqX>4i#BP27Vd*Wj_1v4EB z5+T#ffSYsmg7or0AEGYiiu^*9i6Y}|lmJqX+BRD5i{nCSa}FX1ffRPJ1E>b@#X7To z2H0Hw+nJ-0Nv(xT z6~3spr=lFW)wryKkOTC?F;bF1=r#CPjj$JdHX|WoTn)p~5OokXVZ2_SGNI98(iw7= zcQ@hSiv*fFyjQM2xd?nD0gj#rr$ zX@B{5Wi-W<()ttpRoY(IjwscYO!-pidHqkERE(iu(%etF(xTIUv;F-S4yllxy}K~L z!1{l={r+Q=N=~v;S{FqQ*&YNBL`b!lm;+ziBVJ&IgaVRO`c1Qpdd43{L0rN{Kqo4Y z5=0%}`d!3Vz%(g+CcTy}%l9k>@Ngl)CSs%Ts&nq-eD6GNet+ic`G(Yo!t4jE)0D^P z+)C2cVrN#^c4+gYE2mnQwqIBsX|6IL=|i8ovfFZQEOPfZ17D-}%O|!dRWl)(o3t*J z(SIp(}3IEs~*ISMxT1c^!$l|5-JW8NfR$k%E!zgB#lo?T{{wm9`(uK#Eqqjg=H z^h6tshkn>=b1KEI3K{WNY>GD9f1EL6e9SNV&q6f5JeP1qc!UOEpZ&(jA<+9_(P4f{ z8I~tt3OnLLO{N@I-iI#FTqMzE*i@WPUReDY?<@-4(}hY^9-*G<7T!`XtH^nU z$TQHHfCs4Ep_D9b3rQT0+2w1J5WJM>aj$5THVV^Xovk*Zui_M6`z8nc6>Md|5Utm) z&?0%meGK^<$2V4*m%Jk)n%X-oCfk-;N(#ntXmi*+DkpA7@VPX>E`><)1DYdLiAF29 z6Ril;bd7r$81FoS%k7|$dpT|kjrZkZe0oj*Syj%2LTxSMCGcWp$PaWdmm zUjrk$*^`Li+Ki5dVE!lO-$5nd0-N zCdDTQ`M2$BB*09Qa(d3o=DE+37)P+r9pN^!aF z78$a-K`{l)4&ZF=?Dkwc%QI>2g?sl_$QUC8!yAv2a-pj&5wye>?xS~VyI@l+vau62 zB3;t@!41ai0Dok=A=C*w55_`yo41p&wNDWMhh}ry*=JzH_NBx)d~~sL5LAuXa1)`q zut8zc+F_;3Xz;H%hUmw#)+W~DE^a-O@e>1rGpP!j#@GlDGirRnE#f^_yRC7&E%{FK zmDI532*ts%)9wR{Q31$I+0I%c1RG>VO))aPOAeCbYyo~b!NWG1szNLfN-P-)8t_td zluB7pS~pH%3Xs-S{4{S4^jL?s`={?`Bq0=y7Zw|dUP3{XYlx)l8&N4q<2vc zVXYZ>ot)4Un}ck5I>Rt#>dXl2Y|m6t&3!OSK0_r9in!``mm2WeyqbEID%dXJ_dTpD zD~(XAA*vurn!B7pT^EnUS4cPTkxJZJ(WO*T#@r1MMNODY#6xpQ`aEh`#TWUi)nnm3 z>LdgW_>M8lqI5b`{`ebHTsGGHkeW;0OK}=CmX0thgkIpvxI1gQeD`(~7255ww`*GA z>tt6g6kx=y`^xy+EdrXAxvxz7CXy-Z$Q9s(rp$`RBPmRGr~2RxlWTq=U6QXiEMKJs zaaeg6w3b?(AtE5Icx*v7h@}x<9Qjw9tKw4mb0jC@!1raErPjDV1(D^W3a zJ(iKbVb;)nVKSV1N@AdmUZAfStCR_hV%-<|s8$2-M<}AM?Kx*t73Dq(A=cjneC%}D-Ak;fW+%Q5AL- zPxbF|BA2NY6iaT+NR#?Ah$Iw~Rij8B&7UkS45=N>tnHJ)CMzC<;|<1=k=AwC?{o-Q z{$>sdcDEZ@E{mu}O}Wogu*39t5#t70I@Hw>tfEFIE&b#5!;R??^yMYK2=u>@bLKi! zY9`we3Td+K3e={G`ePyOXw1?SOnh<*kEOtWl>YTsmOA*Ga*GP52eWZ{+Ez>2z&kN!d7 zi(36e|2X0)8^oLSBD7af)5zf0S$I@7O2DS9XU#-5K3i2;$7Pyj3Miz?s%9vqt9+@% zo2>sN^6WXnK>M=^pP32kEx>B)56xs*G5Xu_GmM@y_2|j-7X*IS(?%T z`EQYf;>A0O26Ng;xbN89HR0IJ(q!4OAJyy6mY?GN5*(*dA72FTz3kk}$wS4tQi$^G zN2UnQ4TFW4U|d_0ii{Em!cx9#P>w?CHnNbtqK%Dhs$8@@+^-4bC94%A>KszTIfZIKIkEei zYjaOYj?Tx}dDE!WB)+2fyX=1#i5eA&;jWAKH-Z*Swv5y2@U|nOyQ1<7=2k4iY#@f_ zl^VHvuwFG?uB2YR?YhDAAq())?0x0O)Wp#1juR8yGjWIHmM9=VR(h=4lkT*`h`!6x zz~3G?xmrOY5j9k~v6E^`%&L3RVA=N`o>7QXRIW)9;+4S(A8&##4~fD$VyMww5ZWK( zoqqdv5NX>$8AQ_&BvP{CT*w)O(q;AenZDdZz7HpKOMb+9 z3+#BX>|l`1?h78_&Gc21q&xng1X7+$LKYX)Nc?VPh#R!B6G1034;pTuHNvZV`iY=b zotpYxHEahJ$Q-cVE?%Wyx9hv(Us)&(4rI>2g&9if*9%?_0;rq#V)^np)|&jrySp1f zv%~I6zp#D5yxw9we&^WG8C^tU*O<711yEH~^Cc2eumZze3z|M}YNv0~%dgdE?@e z?1}0GhHzfqiZgv4e&q!#=D{RZ+tea6I3GmV$zyCOPPr{H+|K^N(5PS2(->Yw%F+=W z#q3qdeXRSQ?);)6jf`m#9OD_T>Ly?KR>?D**CYKKJls6JRmRtTo8OsxeMRi+C*4bYFpP<=c68FwT z!&5G1K5N_7l~mKIN1exU%CYIpGrYqoM$9QutY3#(liR6dDyUbvAYYMQl#J}t{+H6! zM|3)Ifhud%nW)0@!Osk{YwBwCJ4qOZggUjn8|C;rk9hW_nGxK&(acGre~lcNzIq^) zPa=!RKN4B!|GP}ZE!@mpZA>jxEnGY--2R7WoTjGWv>=Qeki)Hjra#Y4;h-w|Tv5fT z{`4hRSQ=)CMz*lh^=Qha{J8ajSEoMKcb~~6DvA3F{7EHhO@mfh1qHvxhcA%ra%%PU zeRRd?Oa5;1PtU5+e)6eFZ8gsLQ0gUgeSX9(RZJV6BJk|P)GXGppEo+*C{QjHBmIAm z;z*}4AvNn&3bfOOqmf=zjjO#v2ZSk8G6l7l;e$(MDh9(4j`Jtuer|35+WMG2bp7yl zG&LHgr%h-#vlJDBrCG45`YC&v@g6*<8sBlzkrJ&)!%G!l>K7<~|Exi(?1N7?(PW$* z=`#CAjXNg#6w^?aVu~&}B`+xJGAM%QW#P|-@{jgrzB?7M9ylaAK}_YkAKx{IVk@*4 z?^K2vVwVG+w3{jzcCys6U^lF9K`Z-fywDx2tc8V>`u`Z0RU3R#AlZsM-nUp1w?9-^N@l59e2A{V-J{5W&aVN_?v1gkSp5KD~ z;;=|?e>zBp6yTNJB~T=sUtqC!CR(*GZ04BMu4ff4Iry;I`yaMJYMOmJ{i2|$ zZmH4o7NhI{O z`zO?HqsO4Ry_=AGu97@JcXa$%@#b&t!oV$|65RAVe^i5ijiQFBI;XrKVge6FtE~05 zx*!s%r~#api1%X7T#!-XNJJmR65YVYDsMf4iCOwzHyY&QU#iK3F1`a7Icj8r%@@C! zlFh?eaQ^tP(xl3Gma2je?%7qm*-{37v)HrCv-ya)aybnm{Y$pI>sg?@3A&Kd9#Tc) zpqI)Vd;_D^j-LG~DqM}?NCH?5$(I}NOHcV;Iu9i;p6?r)m18+##ZQq|nqSIHak5S-XGbvVIi+(0{E=Kv}wg~Tyxk#&{n z#G!Wccc3Z|+2u6%ekr(Oy6EXYLT1@L+P)FgJ{_Z9g%k9#66K{Vz5h0u4 zINm^cEI^511Z_TRgRvXiU3$^ZD1@#-dOcoNuwoa8((kqqomvJSANr5VD0OCgvd_A;@& zXf%*RIIsOW2^9Jr8{s`&y#BXTm1G_xNP%~ued8|vUXL*}hy%=L=e@7|mx7mFGl%s- zfgj*M@q10%3CGjdqxVWEB>b`44avh_PlCG$$HSm8u?G(_-Y~qt30pU;_?W^ow2#ax z9!MRdxDf%8wENP!)XWIk{EzBz5d$W)zflHj4{^#JU(OYY^XV2z2fHJDUI+M)U6pQH zpGW}EPGF9iP$JZOs{-;qJ9Tq0mk=S|r3r%W@h}KvQy;&bDCd#%!m!Z`vCd-*z{h*E zNdQz;tn7*K*dQ?r5mx_y@e=7#@nn?Iu2%T?BZM9GKf>G zKyAI1CBzlhr`xHR2poLOWO0Ppo}+7mxiYJeNX4%`PC^vcyZzUJ<6w;${K^qj@0#xW zUy?!ZTLS+Gy%rY&E~u-olv|y?#iIk{VnK4`bW+h#IF8&_R8>9NjV$4M6dOYhcw*j4 zHa&w$N)G{hin&WD`#2|t{qRNFtLh6fNb!Fgq~47t3U@~Y&k3aaEkmmzf=HXZ ztGa+RtP9#gah2<#xsM@DgkINwvCV^w95dbOU+GS%rE>~B`e9$(f>Sz=Rvk#JTpBwW zY6uliHZj2-B;P0bZmjhkbxJa|_CAANY&*9z2v_UQ{|Oy5KStNG@MBHz