Skip to content

Conversation

@fogelito
Copy link
Contributor

@fogelito fogelito commented Jul 8, 2025

Postgres has an issue on bindValue since $sequence is an integer and we send an empty string , so he does not convert empty string to 0 .

Fix issue in Appwrite
appwrite/appwrite#10226
We should not query from the first Place when we have empty data

Summary by CodeRabbit

  • Bug Fixes
    • Improved consistency in database parameter handling for queries, removing special cases for certain fields.
  • Tests
    • Enhanced test coverage by adding an assertion to verify the behavior of empty document sequences.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 8, 2025

Walkthrough

The changes remove special-case logic for handling the :sequence SQL parameter and the _id attribute in the Postgres adapter, unifying parameter binding across all cases. In the test suite, a new assertion checks that a newly created Document instance has an empty sequence value.

Changes

Cohort / File(s) Change Summary
Postgres Adapter SQL Binding Simplification
src/Database/Adapter/Postgres.php
Removed special-case handling for :sequence and _id in parameter binding; now all parameters are bound using getPDOType() for uniformity.
Document Sequence Test Update
tests/e2e/Adapter/Scopes/DocumentTests.php
Added assertion to verify a new Document returns an empty string for getSequence().

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant PostgresAdapter
    participant Database

    Client->>PostgresAdapter: find(query)
    PostgresAdapter->>Database: Prepare SQL with parameters (all bound via getPDOType())
    Database-->>PostgresAdapter: Return results
    PostgresAdapter-->>Client: Return documents
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

Poem

A hop through code, the rabbit spies
No more special cases in disguise!
All bindings now are neat and clean,
The sequence check is left unseen.
Tests confirm the change is sound—
In uniform logic, joy is found!
🐇✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e2549d and 0dc4b12.

📒 Files selected for processing (1)
  • tests/e2e/Adapter/Scopes/DocumentTests.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/e2e/Adapter/Scopes/DocumentTests.php
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cast-sequence

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (2)
src/Database/Database.php (2)

678-690: Remove commented-out code or document its purpose.

This commented-out code block appears to be a PostgreSQL-specific workaround for empty string to integer conversion issues with the $sequence attribute. However, having large blocks of commented code in production reduces readability and can be confusing.

Based on the PR objectives, this issue is being addressed by updating the default sequence value to '0' in the Document class and removing special-case handling in the Postgres adapter. Since this approach has been chosen, this commented code should be removed entirely.

If this code needs to be preserved for reference or future use, consider:

  1. Moving it to a code comment with proper documentation explaining why it was considered but not implemented
  2. Creating a separate issue to track this as a potential alternative approach
-//                    if($query->getAttribute() === '$sequence'){
-//                        /**
-//                         * Hack for Postgres, since bindParam does not convert '' on int attribute
-//                         */
-//                        $values = $query->getValues();
-//                        foreach ($values as $valueIndex => $value) {
-//                            if($value === ''){
-//                                $values[$valueIndex] = '0';
-//                            }
-//                        }
-//                        $query->setValues($values);
-//                        $queries[$index] = $query;
-//                    }

676-677: Fix indentation to resolve linting error.

The pipeline failure indicates a PSR-12 statement indentation issue. The foreach loop appears to have incorrect indentation.

-            foreach ($queries as $index => $query) {
+        foreach ($queries as $index => $query) {
             if ($query->getAttribute() === $attribute->getId()) {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb2f759 and 947ac53.

📒 Files selected for processing (4)
  • src/Database/Adapter/Postgres.php (2 hunks)
  • src/Database/Database.php (1 hunks)
  • src/Database/Document.php (1 hunks)
  • tests/e2e/Adapter/Scopes/DocumentTests.php (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#613
File: src/Database/Adapter/Postgres.php:1254-1319
Timestamp: 2025-07-01T11:31:37.438Z
Learning: In PostgreSQL adapter methods like getUpsertStatement, complexity for database-specific SQL generation is acceptable when the main business logic is properly separated in the parent SQL adapter class, following the adapter pattern where each database adapter handles its own SQL syntax requirements.
src/Database/Adapter/Postgres.php (1)
Learnt from: ArnabChatterjee20k
PR: utopia-php/database#613
File: src/Database/Adapter/Postgres.php:1254-1319
Timestamp: 2025-07-01T11:31:37.438Z
Learning: In PostgreSQL adapter methods like getUpsertStatement, complexity for database-specific SQL generation is acceptable when the main business logic is properly separated in the parent SQL adapter class, following the adapter pattern where each database adapter handles its own SQL syntax requirements.
🧬 Code Graph Analysis (3)
src/Database/Adapter/Postgres.php (2)
src/Database/Adapter/MariaDB.php (1)
  • getPDOType (1957-1965)
src/Database/Adapter/SQL.php (1)
  • getPDOType (1544-1544)
tests/e2e/Adapter/Scopes/DocumentTests.php (4)
src/Database/Document.php (3)
  • Document (12-465)
  • getSequence (67-75)
  • find (299-317)
src/Database/Adapter/Postgres.php (1)
  • find (1390-1552)
src/Database/Database.php (1)
  • find (5971-6132)
src/Database/Query.php (2)
  • Query (8-730)
  • equal (355-358)
src/Database/Database.php (2)
src/Database/Document.php (2)
  • getAttribute (217-224)
  • getId (59-62)
src/Database/Query.php (1)
  • getAttribute (120-123)
🪛 GitHub Actions: Linter
src/Database/Database.php

[error] 1-1: PHP CS Fixer (Laravel Pint) PSR-12 style check failed: statement_indentation issue.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Setup & Build Docker Image
🔇 Additional comments (3)
tests/e2e/Adapter/Scopes/DocumentTests.php (1)

1782-1797: Verify necessity and document limitations of the PostgreSQL “0” sequence workaround

This test correctly exercises the temporary hack in convertQueries that turns an empty getSequence() ("") into "0" to avoid Postgres bind-parameter errors. Before landing this, please confirm and document:

• Semantic correctness
– Does an empty sequence ("") carry a different business meaning than "0"?
• Query behavior
– Could real documents with sequence "0" now collide or return unintended results?
• Cross-database impact
– Other adapters (SQLite, MariaDB) skip empty sequences (if (!empty())), while Postgres will now bind "0". Ensure this change doesn’t break those adapters.

Key locations to review:
• src/Database/Document.php → getSequence()
• src/Database/Database.php → convertQueries() (sequence filter handling)
• src/Database/Adapter/Postgres.php → binding logic around :_sequence
• src/Database/Adapter/SQLite.php & MariaDB.php → how empty sequences are filtered out

As a more robust long-term approach, consider skipping or short-circuiting empty-sequence filters instead of converting to "0". For example, in convertQueries():

if ($field === '$sequence' && (string)$value === '') {
    // Skip sequence‐based filter to avoid binding errors
    continue;
}
src/Database/Adapter/Postgres.php (2)

1507-1507: LGTM! Unified parameter binding resolves sequence casting issue.

The change from hardcoded parameter types to dynamic type determination using getPDOType() correctly addresses the PostgreSQL sequence binding issue described in the PR objectives. This ensures proper type mapping for all parameter values, including the problematic empty string scenarios.


1768-1769: LGTM! Consistent with unified parameter binding approach.

These changes correctly remove special-case handling for sequence parameters, allowing the unified getPDOType() method to handle type determination dynamically. This is consistent with the overall refactoring to address PostgreSQL sequence binding issues.

@fogelito fogelito requested a review from abnegate July 8, 2025 07:15
@abnegate abnegate merged commit cd961f1 into main Jul 31, 2025
15 checks passed
@abnegate abnegate deleted the cast-sequence branch July 31, 2025 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants