FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(sqlalchemy-spanner): quote and escape identifiers in generated DDL by Samin061 · Pull Request #18225 · googleapis/google-cloud-python · GitHub

fix(sqlalchemy-spanner): quote and escape identifiers in generated DDL - #18225

Open
Samin061 wants to merge 3 commits into
googleapis:mainfrom
Samin061:sqlalchemy-spanner-ddl-identifier-quote
Open

fix(sqlalchemy-spanner): quote and escape identifiers in generated DDL#18225
Samin061 wants to merge 3 commits into
googleapis:mainfrom
Samin061:sqlalchemy-spanner-ddl-identifier-quote

Conversation

Copy link
Copy Markdown
Contributor

The PRIMARY KEY and INTERLEAVE IN PARENT clauses that post_create_table appends to generated CREATE TABLE DDL interpolate column and table identifiers raw, unlike the STORING/INTERLEAVE handling in visit_create_index and DROP INDEX which route through self.preparer.quote. A reserved-word or hyphenated primary-key column produces invalid DDL, and a name carrying a backtick (reachable by reflecting a shared database's primary key via get_multi_pk_constraint and recreating it with create_all) terminates the quoted identifier and injects trailing DDL. SpannerIdentifierPreparer also kept the base preparer's double-quote escape, so quote wrapped names in backticks without neutralizing an embedded backtick; this routes the primary-key columns and interleave parent through quote and overrides _escape_identifier to backslash-escape backslash and backtick, matching parse_utils.escape_name.

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Samin061 requested a review from a team as a code owner August 26, 2026 07:40

gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Code Review

This pull request adds escaping for backslashes and backticks inside backtick-quoted identifiers in the Spanner dialect, and applies quoting to primary key columns and interleaved parent table names. Feedback was provided to handle cases where the interleaved parent is passed as a Table object rather than a string, which would otherwise cause an AttributeError during quoting.

Comment on lines 716 to 719
if table.kwargs.get("spanner_interleave_in"):
post_cmds += ",\nINTERLEAVE IN PARENT {}".format(
table.kwargs["spanner_interleave_in"]
self.preparer.quote(table.kwargs["spanner_interleave_in"])
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

If spanner_interleave_in is passed as a Table object (which is common in SQLAlchemy), calling self.preparer.quote() directly on it will raise an AttributeError because quote expects a string identifier. We should check if the object has a name attribute (like a Table object) and extract it before quoting.

        if table.kwargs.get("spanner_interleave_in"):
            parent = table.kwargs["spanner_interleave_in"]
            parent_name = parent.name if hasattr(parent, "name") else parent
            post_cmds += ",\nINTERLEAVE IN PARENT {}".format(
                self.preparer.quote(parent_name)
            )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Hi @Samin061, Please could you take a look?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Good catch. I handled it, though the failure actually happens a bit earlier: spanner_interleave_in is documented as a table name string, but if a Table object is passed the if table.kwargs.get(...) truthiness check itself raises TypeError (Table is a ClauseElement) before quote() is ever reached. So I pull the name out ahead of that guard: parent.name if hasattr(parent, "name") else parent, then quote it. Added unit tests for both the string and Table-object parent.

parthea commented Aug 26, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

@Samin061 , Please could you resolve the file conflict? Tests won't run until the conflict is resolved

parthea assigned sakthivelmanii and unassigned Samin061 Aug 26, 2026
parthea requested a review from sakthivelmanii August 26, 2026 18:11
…l-identifier-quote

# Conflicts:
#	packages/sqlalchemy-spanner/tests/unit/test_dialect.py

Copy link
Copy Markdown
Contributor Author

Merged main in and resolved it. The conflict was just the import block at the top of test_dialect.py, no logic changed. Should be clear to run now.

parthea added kokoro:force-run Add this label to force Kokoro to re-run the tests. kokoro:run Add this label to force Kokoro to re-run the tests. labels Aug 28, 2026
yoshi-kokoro removed kokoro:run Add this label to force Kokoro to re-run the tests. kokoro:force-run Add this label to force Kokoro to re-run the tests. labels Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

4 participants


Back | FazBrowse Home | New Git URL