Skip to content

Conversation

@fogelito
Copy link
Contributor

@fogelito fogelito commented Sep 29, 2025

Summary by CodeRabbit

  • New Features

    • Queries now record attribute types and detect spatial attributes for more reliable spatial filtering.
  • Refactor

    • Simplified SQL condition building by removing an extra parameter across adapters.
    • Streamlined spatial condition handling to use query-aware attribute types.
    • Centralized attribute type propagation during query conversion.
  • Tests

    • Made end-to-end cleanup more robust by using exception-tolerant deletion.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

Walkthrough

Removed the attributes array parameter from SQL condition builders and moved attribute-type awareness into Query; adapters (MariaDB/Postgres) now use Query::isSpatialAttribute and Query::getAttributeType for spatial handling. Database::convertQuery sets Query attributeType. One test switched an existence check to a try-catch delete.

Changes

Cohort / File(s) Summary
Core SQL adapter signatures
src/Database/Adapter/SQL.php
Removed the third parameter from getSQLCondition and getSQLConditions; deleted getAttributeType(...); updated internal call sites and docblocks to omit attributes.
RDBMS adapters (spatial + recursion)
src/Database/Adapter/MariaDB.php, src/Database/Adapter/Postgres.php
Narrowed getSQLCondition signature; replaced array-based spatial checks with Query::isSpatialAttribute(); pass Query::getAttributeType() into spatial handlers; recursive composite-condition calls now omit attributes.
Query attribute typing
src/Database/Query.php
Added attributeType property, setAttributeType() / getAttributeType(), and isSpatialAttribute() predicate to carry attribute type info.
Query conversion pipeline
src/Database/Database.php
convertQuery now sets setAttributeType(attribute['type']) on Query (in addition to on-array handling) so downstream logic can use the attribute type.
Tests
tests/e2e/Adapter/Scopes/GeneralTests.php
Replaced existence-check delete with try-catch around delete; added a local type annotation and a comment.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Database
  participant Query
  participant Adapter as Adapter (MariaDB/Postgres)
  participant Spatial as Spatial Handler

  Client->>Database: request conversion / build Query
  Database->>Query: setOnArray(...), setAttributeType(attribute.type)
  Client->>Adapter: getSQLCondition(Query, binds)
  Adapter->>Query: isSpatialAttribute()
  alt spatial attribute
    Adapter->>Query: getAttributeType()
    Adapter->>Spatial: handleSpatialQueries(query, binds, attribute, type, alias, placeholder)
    Spatial-->>Adapter: spatial SQL fragment
    Adapter-->>Client: composed SQL fragment
  else non-spatial attribute
    Adapter-->>Client: standard SQL fragment
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • abnegate

Poem

I hopped through code and found a clue,
I tucked the type inside Query too.
Spatial paths now whisper true,
Binds are neat and recursions few.
Tiny rabbit cheers — commit, review! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The title highlights removal of spatial attributes injection, which is indeed part of the changes, but it does not capture the broader removal of the attributes parameter from the getSQLCondition and getSQLConditions methods, nor the introduction of attributeType in the Query class and related adapter refactorings. Please update the title to reflect the full scope of the refactoring, such as “Refactor SQL condition methods to remove attributes parameter and unify spatial handling,” so it clearly conveys the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sql-attributes-injection

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adbab90 and 6cdfaf9.

📒 Files selected for processing (1)
  • src/Database/Database.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Database/Database.php
⏰ 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). (10)
  • GitHub Check: Adapter Tests (MariaDB)
  • GitHub Check: Adapter Tests (SharedTables/SQLite)
  • GitHub Check: Adapter Tests (SharedTables/MariaDB)
  • GitHub Check: Adapter Tests (SharedTables/Postgres)
  • GitHub Check: Adapter Tests (Postgres)
  • GitHub Check: Adapter Tests (Mirror)
  • GitHub Check: Adapter Tests (SQLite)
  • GitHub Check: Adapter Tests (SharedTables/MySQL)
  • GitHub Check: Adapter Tests (Pool)
  • GitHub Check: Adapter Tests (MySQL)

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.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Database/Database.php (1)

2041-2051: Logic bug: spatial defaults always trigger “Unknown attribute type”.

Spatial branch lacks a break and falls into default, throwing erroneously whenever a spatial attribute defines a default. Add a break after validating array defaults.

       case self::VAR_POINT:
       case self::VAR_LINESTRING:
       case self::VAR_POLYGON:
           // Spatial types expect arrays as default values
           if ($defaultType !== 'array') {
               throw new DatabaseException('Default value for spatial type ' . $type . ' must be an array');
           }
-          // no break
-      default:
-          throw new DatabaseException('Unknown attribute type: ' . $type . '. Must be one of ' . self::VAR_STRING . ', ' . self::VAR_INTEGER . ', ' . self::VAR_FLOAT . ', ' . self::VAR_BOOLEAN . ', ' . self::VAR_DATETIME . ', ' . self::VAR_RELATIONSHIP . ', ' . self::VAR_POINT . ', ' . self::VAR_LINESTRING . ', ' . self::VAR_POLYGON);
+          break;
+      default:
+          throw new DatabaseException(
+              'Unknown attribute type: ' . $type . '. Must be one of ' .
+              self::VAR_STRING . ', ' . self::VAR_INTEGER . ', ' . self::VAR_FLOAT . ', ' .
+              self::VAR_BOOLEAN . ', ' . self::VAR_DATETIME . ', ' . self::VAR_RELATIONSHIP . ', ' .
+              self::VAR_POINT . ', ' . self::VAR_LINESTRING . ', ' . self::VAR_POLYGON
+          );

Based on learnings

🧹 Nitpick comments (3)
tests/e2e/Adapter/Scopes/GeneralTests.php (1)

440-447: Avoid swallowing real setup errors; narrow the catch or drop the unused variable.

Catching Throwable without handling hides genuine failures (permissions, connectivity). If the intent is “best‑effort cleanup”, consider catching only the expected not‑found exception type, or at minimum remove the unused variable.

Apply to drop the unused variable:

-        } catch (\Throwable $e) {
+        } catch (\Throwable) {
         }

If you prefer to narrow, replace Throwable with the specific adapter exception class you expect here.

src/Database/Query.php (1)

939-962: Harden spatial-type check

Use strict comparison in in_array to avoid edge cases if non-string values flow in.

-    public function isSpatialAttribute(): bool
-    {
-        return in_array($this->attributeType, Database::SPATIAL_TYPES);
-    }
+    public function isSpatialAttribute(): bool
+    {
+        return in_array($this->attributeType, Database::SPATIAL_TYPES, true);
+    }
src/Database/Adapter/Postgres.php (1)

1609-1615: Prefix alias in full-text SEARCH/NOT_SEARCH

These branches reference only the quoted column name without the table alias. For consistency with the rest of the method and to avoid ambiguity, prefix with {$alias}.

- return "to_tsvector(regexp_replace({$attribute}, '[^\\w]+',' ','g')) @@ websearch_to_tsquery(:{$placeholder}_0)";
+ return "to_tsvector(regexp_replace({$alias}.{$attribute}, '[^\\w]+',' ','g')) @@ websearch_to_tsquery(:{$placeholder}_0)";
- return "NOT (to_tsvector(regexp_replace({$attribute}, '[^\\w]+',' ','g')) @@ websearch_to_tsquery(:{$placeholder}_0))";
+ return "NOT (to_tsvector(regexp_replace({$alias}.{$attribute}, '[^\\w]+',' ','g')) @@ websearch_to_tsquery(:{$placeholder}_0))";

Also applies to: 1612-1615

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19a3ab2 and adbab90.

📒 Files selected for processing (6)
  • src/Database/Adapter/MariaDB.php (3 hunks)
  • src/Database/Adapter/Postgres.php (3 hunks)
  • src/Database/Adapter/SQL.php (5 hunks)
  • src/Database/Database.php (1 hunks)
  • src/Database/Query.php (2 hunks)
  • tests/e2e/Adapter/Scopes/GeneralTests.php (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
tests/e2e/Adapter/Scopes/GeneralTests.php (4)
src/Database/Database.php (2)
  • getDatabase (779-782)
  • delete (1300-1314)
src/Database/Adapter.php (2)
  • getDatabase (160-163)
  • delete (515-515)
tests/e2e/Adapter/Base.php (1)
  • getDatabase (36-36)
src/Database/Mirror.php (1)
  • delete (192-195)
src/Database/Adapter/SQL.php (3)
src/Database/Adapter/MariaDB.php (1)
  • getSQLCondition (1485-1578)
src/Database/Adapter/Postgres.php (1)
  • getSQLCondition (1581-1674)
src/Database/Query.php (3)
  • Query (8-1116)
  • getValues (167-170)
  • getMethod (151-154)
src/Database/Adapter/Postgres.php (3)
src/Database/Adapter/MariaDB.php (1)
  • getSQLCondition (1485-1578)
src/Database/Adapter/SQL.php (1)
  • getSQLCondition (1799-1799)
src/Database/Query.php (2)
  • Query (8-1116)
  • isSpatialAttribute (958-961)
src/Database/Database.php (2)
src/Database/Query.php (3)
  • getAttribute (159-162)
  • setOnArray (934-937)
  • setAttributeType (943-946)
src/Database/Document.php (1)
  • getAttribute (224-231)
src/Database/Query.php (1)
src/Database/Database.php (1)
  • Database (37-7359)
src/Database/Adapter/MariaDB.php (3)
src/Database/Adapter/Postgres.php (2)
  • getSQLCondition (1581-1674)
  • handleSpatialQueries (1510-1571)
src/Database/Adapter/SQL.php (1)
  • getSQLCondition (1799-1799)
src/Database/Query.php (3)
  • Query (8-1116)
  • isSpatialAttribute (958-961)
  • getAttributeType (951-954)
⏰ 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 (7)
tests/e2e/Adapter/Scopes/GeneralTests.php (1)

427-429: Docblock addition looks good.

Local Database typing improves IDE/static analysis in this test.

src/Database/Database.php (1)

7114-7130: Confirm Postgres spatial handler consumes attributeType
MariaDB adapter passes attributeType; please verify Postgres’s handleSpatialQueries reads Query::getAttributeType() internally:

rg -nP -C3 'getAttributeType\(' src/Database/Adapter/Postgres.php
src/Database/Query.php (1)

113-115: New attributeType state looks good

Property addition is straightforward and aligns with adapter usage.

src/Database/Adapter/Postgres.php (1)

1581-1594: Signature update and spatial gate: LGTM

Removing the attributes param and switching to $query->isSpatialAttribute() is consistent with the new Query API and SQL base class.

src/Database/Adapter/SQL.php (2)

1799-1800: Abstract and helper signatures aligned: LGTM

Removing the attributes parameter tightens the API; recursive/nested calls updated correctly.

Also applies to: 1808-1820


2419-2421: Call-site updates: LGTM; optional sanity check

find/count/sum now call getSQLConditions without attributes as expected. If you want extra safety, run the repo-wide check above to ensure no missed call-sites.

Also applies to: 2543-2546, 2619-2622

src/Database/Adapter/MariaDB.php (1)

1485-1497: LGTM – getSQLCondition signature and spatial branch align with Query changes, and no outdated call-sites remain.

@fogelito fogelito requested a review from abnegate September 30, 2025 05:17
@abnegate abnegate merged commit 398b5d5 into main Sep 30, 2025
15 checks passed
@abnegate abnegate deleted the sql-attributes-injection branch September 30, 2025 07:24
@coderabbitai coderabbitai bot mentioned this pull request Nov 24, 2025
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