Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Aug 27, 2025

Summary by CodeRabbit

  • New Features
    • Respects custom table/column names from schema mapping across DDL and constraints.
    • Adds a literal-extraction helper to the schema utilities.
  • Bug Fixes
    • Unified relation JSON selection behavior across SQLite and PostgreSQL for consistent results.
    • Improved name mapping for SELECT/INSERT/UPDATE/DELETE, including correct expansion of SELECT * and joins.
  • Refactor
    • Major overhaul of query name-mapping internals to improve stability without changing public APIs.
  • Tests
    • Added cross-provider tests for count, aggregate, and groupBy.

Copilot AI review requested due to automatic review settings August 27, 2025 11:30
@coderabbitai
Copy link

coderabbitai bot commented Aug 27, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Unifies synthesized JSON aliasing to $t in PostgreSQL and SQLite CRUD dialects, refactors QueryNameMapper to scope-based processing, adds schema name mapping support (@@map/@map) via helpers, introduces ExpressionUtils.getLiteralValue, and adds tests for count/aggregate/groupBy across SQLite and PostgreSQL.

Changes

Cohort / File(s) Summary
CRUD dialect JSON alias unification
packages/runtime/src/client/crud/dialects/postgresql.ts, packages/runtime/src/client/crud/dialects/sqlite.ts
Replaced synthesized JSON aliases ($j / data) with $t across relation selection, JSON object construction, and related argument paths; no control-flow or API signature changes.
Executor name-mapper refactor
packages/runtime/src/client/executor/name-mapper.ts
Reworked QueryNameMapper to use scope-based processing (per-table processing, scoped resolution, select-* expansion), added helper routines (processSelectTable, createSelectAllFields, extractModelName, etc.), removed old from/join scoping helpers; public API unchanged.
Schema DB name mapping
packages/runtime/src/client/helpers/schema-db-pusher.ts
Added getTableName/getColumnName helpers to honor @@map/@map mappings and updated table/column/PK/unique/FK creation to use mapped names.
Expression utilities
packages/runtime/src/schema/expression.ts
Added ExpressionUtils.getLiteralValue(expr) returning a literal string
Tests: name mapping aggregates
packages/runtime/test/client-api/name-mapping.test.ts
Added tests (count, aggregate, groupBy) running against SQLite and PostgreSQL, exercising ORM and Kysely query paths.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

I nibble through names with twitching nose,
From $j to $t the tidy path grows.
Tables mapped, columns neatly dressed,
Counts and groups in clover rest.
A rabbit's hop — the queries blessed. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0209d16 and 91be56d.

📒 Files selected for processing (1)
  • packages/runtime/src/client/executor/name-mapper.ts (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/runtime/src/client/executor/name-mapper.ts
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/name-mapper-1

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@claude
Copy link

claude bot commented Aug 27, 2025

Claude finished @ymc9's task —— View job


PR Review: Refactor Name Mapper

I'll review this PR focusing on the name mapper refactoring changes.

Review Tasks:

  • Analyze the core name-mapper.ts changes
  • Review database dialect modifications
  • Examine test coverage additions
  • Check for potential bugs and performance issues
  • Assess security considerations
  • Provide overall feedback and recommendations

Analysis Complete

The refactoring successfully eliminates nested queries in the name mapping logic by introducing a more sophisticated scope-based approach. Here's my detailed review:

✅ Code Quality & Architecture

Excellent refactoring approach:

  • The new scope-based system (lines 23-27 in name-mapper.ts) cleanly separates concerns
  • The namesMapped flag prevents double-mapping, which was the core issue
  • Proper use of TypeScript for type safety throughout

Well-structured transformations:

  • Each query type (SELECT, INSERT, UPDATE, DELETE) has dedicated handling
  • The processSelectTable method (lines 345-373) intelligently decides when names need mapping
  • Clean separation between table/field name mapping and alias handling

✅ Performance Improvements

Key optimization achieved:

  • Before: Nested queries created for every table with mapped columns
  • After: Direct table references with aliases, eliminating subquery overhead
  • The hasMappedColumns check (lines 340-342) efficiently determines mapping necessity

Database dialect optimizations:

  • PostgreSQL: Maintains lateral joins but avoids unnecessary nesting
  • SQLite: Direct column reference approach, avoiding subquery complexity

✅ Test Coverage

Comprehensive test additions (196 new lines):

  • Tests all CRUD operations with name mapping
  • Covers both ORM-level and Kysely query builder usage
  • Tests complex scenarios like joins, aggregations, and groupBy operations
  • Validates both PostgreSQL and SQLite dialects

⚠️ Potential Issues

Minor concerns:

  1. Line 238: this.scopes.toReversed() - This is a newer Array method, ensure Node.js version compatibility
  2. Error handling: Some methods lack null checks (e.g., line 444-445 in extractModelName)
  3. Performance: The scope resolution loop (lines 237-272) could be optimized for deeply nested scopes

✅ Security Assessment

No security concerns identified:

  • No dynamic SQL injection risks
  • Proper parameter binding maintained
  • Schema validation intact

📝 Recommendations

Suggestions for improvement:

  1. Compatibility fix:

    // Replace line 238
    for (const scope of [...this.scopes].reverse()) {
  2. Add null safety:

    // In extractModelName method (line 444)
    private extractModelName(node: OperationNode): string | undefined {
        const { node: innerNode } = stripAlias(node);
        return TableNode.is(innerNode) ? innerNode.table.identifier.name : undefined;
    }
  3. Consider caching scope lookups for better performance in complex queries

✅ Overall Assessment

Excellent refactoring work! This PR successfully:

  • ✅ Eliminates unnecessary nested queries
  • ✅ Maintains full backward compatibility
  • ✅ Improves performance for name-mapped schemas
  • ✅ Adds comprehensive test coverage
  • ✅ Uses clean, maintainable architecture

Performance impact: Significant improvement for schemas with @map attributes, no impact for unmapped schemas.

Breaking changes: None - fully backward compatible.


Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the name mapping logic to avoid creating nested queries when handling database table and column name mappings. The changes optimize query generation by processing table selections differently and expanding select-all operations inline rather than wrapping them in subqueries.

Key changes:

  • Refactored name mapping logic to process table selections more efficiently without nested queries
  • Updated select-all expansion to work inline with proper aliasing
  • Fixed column alias references in SQL dialect implementations

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/runtime/src/schema/expression.ts Added utility method to extract literal values from expressions
packages/runtime/src/client/helpers/schema-db-pusher.ts Enhanced to use name mapping for table and column names when creating database schema
packages/runtime/src/client/executor/name-mapper.ts Major refactor of query name mapping logic to avoid nested queries
packages/runtime/src/client/crud/dialects/sqlite.ts Updated column alias from '$j' to '$t'
packages/runtime/src/client/crud/dialects/postgresql.ts Updated column alias from '$j' to '$t'
packages/runtime/test/client-api/name-mapping.test.ts Added comprehensive tests for count, aggregate, and groupBy operations

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@claude
Copy link

claude bot commented Aug 27, 2025

Claude finished @ymc9's task —— View job


Claude finished @ymc9's task —— View job


PR Review: Refactor Name Mapper

I'll review this PR focusing on the name mapper refactoring changes.

Review Tasks:

  • Analyze the core name-mapper.ts changes
  • Review database dialect modifications
  • Examine test coverage additions
  • Check for potential bugs and performance issues
  • Assess security considerations
  • Provide overall feedback and recommendations

Analysis Complete

The refactoring successfully eliminates nested queries in the name mapping logic by introducing a more sophisticated scope-based approach. Here's my detailed review:

✅ Code Quality & Architecture

Excellent refactoring approach:

  • The new scope-based system (lines 23-27 in name-mapper.ts) cleanly separates concerns
  • The namesMapped flag prevents double-mapping, which was the core issue
  • Proper use of TypeScript for type safety throughout

Well-structured transformations:

  • Each query type (SELECT, INSERT, UPDATE, DELETE) has dedicated handling
  • The processSelectTable method (lines 345-373) intelligently decides when names need mapping
  • Clean separation between table/field name mapping and alias handling

✅ Performance Improvements

Key optimization achieved:

  • Before: Nested queries created for every table with mapped columns
  • After: Direct table references with aliases, eliminating subquery overhead
  • The hasMappedColumns check (lines 340-342) efficiently determines mapping necessity

Database dialect optimizations:

  • PostgreSQL: Maintains lateral joins but avoids unnecessary nesting
  • SQLite: Direct column reference approach, avoiding subquery complexity

✅ Test Coverage

Comprehensive test additions (196 new lines):

  • Tests all CRUD operations with name mapping
  • Covers both ORM-level and Kysely query builder usage
  • Tests complex scenarios like joins, aggregations, and groupBy operations
  • Validates both PostgreSQL and SQLite dialects

⚠️ Potential Issues

Minor concerns:

  1. Line 238: this.scopes.toReversed() - This is a newer Array method, ensure Node.js version compatibility
  2. Error handling: Some methods lack null checks (e.g., line 444-445 in extractModelName)
  3. Performance: The scope resolution loop (lines 237-272) could be optimized for deeply nested scopes

✅ Security Assessment

No security concerns identified:

  • No dynamic SQL injection risks
  • Proper parameter binding maintained
  • Schema validation intact

📝 Recommendations

Suggestions for improvement:

  1. Compatibility fix:

    // Replace line 238
    for (const scope of [...this.scopes].reverse()) {
  2. Add null safety:

    // In extractModelName method (line 444)
    private extractModelName(node: OperationNode): string | undefined {
        const { node: innerNode } = stripAlias(node);
        return TableNode.is(innerNode) ? innerNode.table.identifier.name : undefined;
    }
  3. Consider caching scope lookups for better performance in complex queries

✅ Overall Assessment

Excellent refactoring work! This PR successfully:

  • ✅ Eliminates unnecessary nested queries
  • ✅ Maintains full backward compatibility
  • ✅ Improves performance for name-mapped schemas
  • ✅ Adds comprehensive test coverage
  • ✅ Uses clean, maintainable architecture

Performance impact: Significant improvement for schemas with @map attributes, no impact for unmapped schemas.

Breaking changes: None - fully backward compatible.


Copy link

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
packages/runtime/src/client/helpers/schema-db-pusher.ts (1)

93-103: Base-model FK doesn’t respect mapped table/column names

The delegate FK uses raw modelDef.baseModel and baseModelDef.idFields without applying getTableName/getColumnName. This will break when the base model or its id fields are mapped.

Apply mapping to both local and referenced sides:

         if (modelDef.baseModel) {
             // create fk constraint
             const baseModelDef = requireModel(this.schema, modelDef.baseModel);
-            table = table.addForeignKeyConstraint(
-                `fk_${modelDef.baseModel}_delegate`,
-                baseModelDef.idFields,
-                modelDef.baseModel,
-                baseModelDef.idFields,
-                (cb) => cb.onDelete('cascade').onUpdate('cascade'),
-            );
+            table = table.addForeignKeyConstraint(
+                `fk_${modelDef.baseModel}_delegate`,
+                // local columns on the concrete model
+                modelDef.idFields.map((f) => this.getColumnName(modelDef.fields[f]!)),
+                // referenced table and columns (base model)
+                this.getTableName(baseModelDef),
+                baseModelDef.idFields.map((f) => this.getColumnName(baseModelDef.fields[f]!)),
+                (cb) => cb.onDelete('cascade').onUpdate('cascade'),
+            );
         }
🧹 Nitpick comments (5)
packages/runtime/src/client/helpers/schema-db-pusher.ts (1)

145-149: Constraint names still use model names (not mapped) — confirm intent

PK/unique constraint names continue to use modelDef.name. If you want DB artifacts to reflect mapped names, consider switching to getTableName(modelDef) for naming consistency.

Also applies to: 165-171

packages/runtime/src/client/executor/name-mapper.ts (4)

288-295: Pop scopes robustly even if nested code pushes/pops

Current forEach(() => pop()) assumes no extra pushes/pops occurred inside fn. Restore to a saved length to be safe.

-    private withScopes<T>(scopes: Scope[], fn: (...args: unknown[]) => T): T {
-        scopes.forEach((s) => this.pushScope(s));
-        try {
-            return fn();
-        } finally {
-            scopes.forEach(() => this.scopes.pop());
-        }
-    }
+    private withScopes<T>(scopes: Scope[], fn: (...args: unknown[]) => T): T {
+        const baseLen = this.scopes.length;
+        scopes.forEach((s) => this.pushScope(s));
+        try {
+            return fn();
+        } finally {
+            this.scopes.length = baseLen;
+        }
+    }

311-321: Support positional @map/@@Map and guard non-literal args

Only reading a named name arg misses common positional usage and non-literal values.

-        const mapAttr = def.attributes?.find((attr) => attr.name === '@@map' || attr.name === '@map');
-        if (mapAttr) {
-            const nameArg = mapAttr.args?.find((arg) => arg.name === 'name');
-            if (nameArg && nameArg.value.kind === 'literal') {
-                return nameArg.value.value as string;
-            }
-        }
+        const mapAttr = def.attributes?.find((a) => a.name === '@@map' || a.name === '@map');
+        if (mapAttr) {
+            const arg = mapAttr.args?.find((a) => a.name === 'name') ?? mapAttr.args?.[0];
+            const v = arg?.value;
+            if (v && v.kind === 'literal' && typeof v.value === 'string') {
+                return v.value as string;
+            }
+        }
         return undefined;

If you have a helper to extract literal values, consider delegating to it here.


352-360: Avoid aliasing to the same name when no table mapping is needed

Always aliasing to the model name adds noise (FROM users AS users). Only alias when the physical table name differs or an explicit alias is provided.

-            const modelName = innerNode.table.identifier.name;
-            const mappedName = this.mapTableName(modelName);
-            return {
-                node: this.wrapAlias(TableNode.create(mappedName), alias ?? modelName),
-                scope: {
-                    alias: alias ?? modelName,
+            const modelName = innerNode.table.identifier.name;
+            const mappedName = this.mapTableName(modelName);
+            const effectiveAlias = alias ?? (mappedName !== modelName ? modelName : undefined);
+            return {
+                node: this.wrapAlias(TableNode.create(mappedName), effectiveAlias),
+                scope: {
+                    alias: effectiveAlias,
                     model: modelName,
                     namesMapped: !this.hasMappedColumns(modelName),
                 },
             };

170-178: Nil-guard for Delete.from

Minor: if Kysely ever emits a Delete without from (unlikely), this throws. Safe-guarding avoids surprises.

-        const scopes: Scope[] = node.from.froms.map((node) => {
+        const scopes: Scope[] = node.from?.froms?.map((node) => {
             // ...
-        });
+        }) ?? [];

Apply the same guard where froms is re-mapped below.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2390469 and 0209d16.

📒 Files selected for processing (6)
  • packages/runtime/src/client/crud/dialects/postgresql.ts (4 hunks)
  • packages/runtime/src/client/crud/dialects/sqlite.ts (1 hunks)
  • packages/runtime/src/client/executor/name-mapper.ts (9 hunks)
  • packages/runtime/src/client/helpers/schema-db-pusher.ts (5 hunks)
  • packages/runtime/src/schema/expression.ts (1 hunks)
  • packages/runtime/test/client-api/name-mapping.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
{packages,samples,tests}/**

📄 CodeRabbit inference engine (CLAUDE.md)

Packages are located in packages/, samples/, and tests/

Files:

  • packages/runtime/src/schema/expression.ts
  • packages/runtime/src/client/crud/dialects/sqlite.ts
  • packages/runtime/test/client-api/name-mapping.test.ts
  • packages/runtime/src/client/crud/dialects/postgresql.ts
  • packages/runtime/src/client/helpers/schema-db-pusher.ts
  • packages/runtime/src/client/executor/name-mapper.ts
🧬 Code graph analysis (3)
packages/runtime/src/schema/expression.ts (1)
packages/sdk/src/schema/expression.ts (1)
  • Expression (1-10)
packages/runtime/src/client/helpers/schema-db-pusher.ts (3)
packages/sdk/src/schema/schema.ts (2)
  • ModelDef (20-36)
  • FieldDef (59-74)
packages/runtime/src/schema/expression.ts (1)
  • ExpressionUtils (16-116)
packages/runtime/src/client/query-utils.ts (1)
  • requireModel (20-26)
packages/runtime/src/client/executor/name-mapper.ts (3)
packages/runtime/src/client/executor/kysely-utils.ts (1)
  • stripAlias (7-14)
packages/runtime/src/client/query-utils.ts (2)
  • getModel (16-18)
  • requireModel (20-26)
packages/common-helpers/src/tiny-invariant.ts (1)
  • invariant (4-14)
⏰ 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: build-test (20.x)
🔇 Additional comments (12)
packages/runtime/src/client/crud/dialects/sqlite.ts (1)

213-219: Confirm: legacy JSON alias $j fully replaced
Verified via RipGrep across packages/runtime/src/client that there are no remaining references to $j, either as an identifier or as a string literal. Merging approved.

packages/runtime/src/schema/expression.ts (1)

113-115: Helper is precise and side-effect free — LGTM

getLiteralValue cleanly narrows for literals and returns undefined otherwise.

packages/runtime/src/client/crud/dialects/postgresql.ts (1)

63-64: PostgreSQL JSON alias consistency confirmed – no $j references remain

All JSON alias occurrences have been switched from “$j” to “$t” in selection, aggregation, and nested relation references. A repository‐wide search for any lingering “.$j” paths under packages/runtime/src/client returned no matches, confirming that there are no stale references.

• Snippet at packages/runtime/src/client/crud/dialects/postgresql.ts:63–64 remains as:

return joinedQuery.select(`${parentAlias}$${relationField}.$t as ${relationField}`);

• No occurrences of \.\$j\b were found in the client runtime code.

packages/runtime/src/client/helpers/schema-db-pusher.ts (2)

75-79: Table creation now respects @@Map — LGTM

Using getTableName at creation time is the right hook for mapped model names.


273-281: FK creation now respects mapped names — LGTM

Good application of getTableName/getColumnName for FK sides.

packages/runtime/test/client-api/name-mapping.test.ts (3)

239-276: Count tests cover ORM and Kysely paths — LGTM

Good coverage including relation-filtered counts and type coercion for provider differences.


278-341: Aggregate tests validate both ORM and Kysely — LGTM

Solid assertions across _count/_min/_max and filtered aggregates.


343-433: GroupBy tests are comprehensive — LGTM

Covers by/having paths and cross-checks with Kysely groupBy.

packages/runtime/src/client/executor/name-mapper.ts (4)

202-235: Selection mapping logic is good; preserves original field names

Expanding select * only when needed and aliasing mapped columns back to original names is correct. Nice.


109-138: Reference/table qualifier handling looks correct

Qualifier resolution respects aliases vs models and only maps the table name when the qualifier is a model. Good.


238-238: Ensure Node 20+ Support or Refactor Array Reverse

It looks like neither your root nor packages/runtime package.json declare an engines.node field, so it isn’t guaranteed you’re targeting Node 20 or lib.es2023. You should either:

  • Add an explicit engines.node entry (e.g. "engines": { "node": ">=20" }) to all relevant package.json files before using toReversed().
  • Or replace toReversed() with a manual reverse loop for broader compatibility.

Locations to review:

  • package.json (project root)
  • packages/runtime/package.json

Suggested alternative:

-        for (const scope of this.scopes.toReversed()) {
+        for (let i = this.scopes.length - 1; i >= 0; i--) {
+            const scope = this.scopes[i]!;

62-75: Map JOIN … USING and guard against missing on

The current code only handles join.on (unconditionally calling this.transformNode(join.on)) and ignores the join.using property. Kysely’s AST represents USING clauses with a UsingNode (a subtype of OperationNode), and the JoinType enum includes "Using", so joins using USING (…) will have join.using set and join.on undefined (kysely-org.github.io). Unconditionally transforming join.on will crash for USING joins, and the using columns remain unmapped under name-mapped schemas.

Please update the join transformation to:

-            const joins = node.joins
-                ? node.joins.map((join, i) => ({
-                      ...join,
-                      table: processedJoins[i]!.node,
-                      on: this.transformNode(join.on),
-                  }))
-                : undefined;
+            const joins = node.joins
+                ? node.joins.map((join, i) => ({
+                      ...join,
+                      table: processedJoins[i]!.node,
+                      // only transform ON if present
+                      on:    join.on    ? this.transformNode(join.on)    : undefined,
+                      // transform USING columns when present
+                      using: join.using ? this.transformNode(join.using) : undefined,
+                  }))
+                : undefined;

• Ensure that using columns are correctly mapped through transformNode, and guard join.on since it may be undefined for USING joins.
• Add or extend a test building a query with JOIN … USING (mapped_col) and assert that the output SQL uses the mapped column name. I can draft the test if needed.

@ymc9 ymc9 merged commit 5846a81 into dev Aug 27, 2025
7 checks passed
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.

2 participants