Skip to content

Conversation

@ansutung
Copy link

@ansutung ansutung commented Oct 3, 2025

Summary by CodeRabbit

  • New Features

    • Added connectors for Redshift, Postgres, SQL Server, and Canner.
    • DuckDB can attach additional databases and list/attach files from S3 or local storage.
    • Query results now return as Apache Arrow tables for improved performance and compatibility.
    • Automatic handling of Decimal and UUID types for consistent outputs.
  • Bug Fixes

    • Unified, clearer error messages across connectors; safer dry-run behavior.
    • More robust connection closing to prevent crashes or double-closing.
    • MSSQL correctly handles Unicode string literals.
    • Preserved timeout semantics while improving invalid SQL detection.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Adds multiple connectors (Redshift, Postgres, MSSQL, Canner), changes query return type to PyArrow tables, introduces unified error handling, implements close semantics, enhances DuckDB behaviors, and adds utilities for UUID/Decimal post-processing and PostgreSQL type-name retrieval in ibis-server/app/model/connector.py.

Changes

Cohort / File(s) Summary of Changes
Connector additions
ibis-server/app/model/connector.py
Introduces RedshiftConnector, PostgresConnector, MSSqlConnector, and CannerConnector with query/dry_run implementations and close methods.
API return type updates
ibis-server/app/model/connector.py
Updates Connector.query and SimpleConnector.query to return pa.Table instead of pandas DataFrame.
Unified error handling
ibis-server/app/model/connector.py
Wraps backend exceptions into WrenError with ErrorCode/ErrorPhase; adjusts mappings (e.g., timeouts vs INVALID_SQL) across query and dry_run.
PyArrow post-processing
ibis-server/app/model/connector.py
Adds _handle_pyarrow_unsupported_type, _cast_uuid_columns, _round_decimal_columns in SimpleConnector to cast UUIDs to string and round Decimals to a fixed scale.
Close semantics and safety
ibis-server/app/model/connector.py
Adds close() methods to multiple connectors with safeguards to avoid double-closing and segfaults.
DuckDB enhancements
ibis-server/app/model/connector.py
Enables attaching additional DuckDB databases, listing/attaching files via S3/Local FS interfaces, and improves dry_run/close safety.
PostgreSQL type helper
ibis-server/app/model/connector.py
Adds _get_pg_type_names(connection) to retrieve PostgreSQL OID-to-type-name mappings.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Connector as SimpleConnector
  participant Ibis as Ibis Backend
  participant Arrow as PyArrow
  Note over Connector,Ibis: Query execution with PyArrow result
  Client->>Connector: query(sql, limit)
  Connector->>Ibis: compile/execute(sql, limit)
  Ibis-->>Connector: result (backend table)
  rect rgb(245,245,255)
    Note right of Connector: Post-process unsupported types
    Connector->>Connector: _handle_pyarrow_unsupported_type()
    Connector->>Connector: _cast_uuid_columns()
    Connector->>Connector: _round_decimal_columns(scale=9)
  end
  Connector->>Arrow: to_arrow()
  Arrow-->>Connector: pa.Table
  Connector-->>Client: pa.Table
Loading
sequenceDiagram
  autonumber
  actor Client
  participant Conn as AnyConnector
  participant Backend as Driver/DB
  participant Err as WrenError
  Note over Conn,Backend: Unified error handling for query/dry_run
  Client->>Conn: dry_run(sql) / query(sql)
  Conn->>Backend: execute / explain
  alt Success
    Backend-->>Conn: OK / result
    Conn-->>Client: Response
  else Backend raises (Trino/ClickHouse/psycopg/...)
    Backend-->>Conn: Exception
    rect rgb(255,245,245)
      Note right of Conn: Map to ErrorCode + ErrorPhase
      Conn->>Err: wrap(exception)
    end
    Err-->>Client: WrenError
  end
Loading
sequenceDiagram
  autonumber
  actor Client
  participant RS as RedshiftConnector
  participant Psy as psycopg Cursor
  participant Arrow as PyArrow
  Note over RS,Psy: Redshift autocommit + Python-level cursor
  Client->>RS: query(sql, limit)
  RS->>Psy: execute(sql)
  Psy-->>RS: rows / cursor data
  RS->>Arrow: to_arrow()
  Arrow-->>RS: pa.Table
  RS-->>Client: pa.Table
  Client->>RS: close()
  RS-->>Client: closed
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

ibis, python

Suggested reviewers

  • douenergy
  • goldmedal

Poem

(\/)
( •
•)✧ hop!
New bridges built to data streams,
UUIDs tamed, and Decimal gleams.
Errors corralled, one burrowed voice—
Arrow feathers our swift choice.
Close the tunnel—quiet, poised.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.50% which is insufficient. The required threshold is 80.00%. You can run `@coderabbitai generate docstrings` to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit's high-level summary is enabled.
Title Check ✅ Passed The title mentions adding an N prefix for MSSQL Unicode literals, which corresponds to a valid subset of the changes. However, it does not reflect the primary objective of this pull request, which is the broad expansion of multi-backend support—including new Redshift, Postgres, MSSQL, and Canner connectors—along with enhanced PyArrow handling, unified error wrapping, and robust closing logic.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added ibis python Pull requests that update Python code labels Oct 3, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95bc169 and 78c5624.

📒 Files selected for processing (1)
  • ibis-server/app/model/connector.py (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ibis-server/app/model/connector.py (6)
ibis-server/tests/routers/v2/connector/test_postgres.py (1)
  • postgres (136-149)
ibis-server/app/model/__init__.py (3)
  • GcsFileConnectionInfo (318-338)
  • MinioFileConnectionInfo (292-315)
  • S3FileConnectionInfo (271-289)
ibis-server/app/model/data_source.py (3)
  • DataSource (42-67)
  • get_connection (57-61)
  • get_connection (88-98)
ibis-server/app/routers/v2/connector.py (1)
  • query (45-151)
ibis-server/app/routers/v3/connector.py (1)
  • query (41-153)
ibis-server/tests/routers/v2/connector/test_mssql.py (1)
  • mssql (80-107)

Comment on lines +321 to +324
ibis_table = self.connection.sql(sql)
if limit is not None:
ibis_table = ibis_table.limit(limit)
return self._round_decimal_columns(ibis_table)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Unicode prefix never reaches MSSQL execution.

fixed_sql is computed with _add_unicode_prefix, but the subsequent self.connection.sql(sql) call still runs the original SQL, so the N-prefix fix is lost and Unicode literals stay broken. Apply the fix to use the rewritten SQL.

-        ibis_table = self.connection.sql(sql)
+        ibis_table = self.connection.sql(fixed_sql)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ibis_table = self.connection.sql(sql)
if limit is not None:
ibis_table = ibis_table.limit(limit)
return self._round_decimal_columns(ibis_table)
ibis_table = self.connection.sql(fixed_sql)
if limit is not None:
ibis_table = ibis_table.limit(limit)
return self._round_decimal_columns(ibis_table)
🤖 Prompt for AI Agents
In ibis-server/app/model/connector.py around lines 321 to 324, the method
computes a rewritten SQL (fixed_sql) with _add_unicode_prefix but then calls
self.connection.sql(sql) so the N-prefix never reaches MSSQL; change the call to
use the rewritten SQL (e.g., self.connection.sql(fixed_sql)), ensuring fixed_sql
is created (call _add_unicode_prefix(sql) if not already) before applying limit
and returning the rounded table.

@goldmedal
Copy link
Contributor

@ansutung, could you rebase on the latest main and add the description for what you want to propose?

@goldmedal
Copy link
Contributor

It may be a duplicate of #1338

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ibis python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants