Skip to content

orm: fix u8/i8 OID mapping and string default quoting - #27989

Open
Jengro777 wants to merge 6 commits into
vlang:masterfrom
Jengro777:fix/orm-u8-oid-and-string-default-quoting
Open

orm: fix u8/i8 OID mapping and string default quoting#27989
Jengro777 wants to merge 6 commits into
vlang:masterfrom
Jengro777:fix/orm-u8-oid-and-string-default-quoting

Conversation

@Jengro777

Copy link
Copy Markdown
Contributor

Fix #27986u8 and i8 bound as wrong PostgreSQL type

Before: u8 and i8 were bound as Oid.t_char (PostgreSQL internal "char" type, OID 18), causing:

ERROR: column "status" is of type smallint but expression is of type "char"

After: Both map to Oid.t_int2 (smallint) with proper conv.hton16() byte-order conversion, consistent with i16/u16.

Type Before (OID) After (OID) Conversion
u8 t_char (18) t_int2 (21) conv.hton16(u16(data))
i8 t_char (18) t_int2 (21) conv.hton16(u16(data))

Values verify correctly:

  • u8(255)u16(255) → int2 reads 255 ✅
  • i8(-1)u16(65535) → int2 reads -1 ✅ (matches i16 pattern)

Fix #27987 — String default: values not quoted in DDL

Before: @[default: '\''/dashboard'\''] generated invalid SQL:

"home_path" VARCHAR(255) DEFAULT /dashboard NOT NULL  -- syntax error

After: String defaults are properly quoted:

"home_path" VARCHAR(255) DEFAULT '\''/dashboard'\'' NOT NULL

Numeric defaults remain unquoted (DEFAULT 0, DEFAULT 33), and empty string defaults (DEFAULT '\'''\'') continue to work via the existing explicit branch.

Breaking change: The @[default: '\''"...'\''] workaround (embedding manual double-quotes) is no longer needed. Tests updated accordingly.


Files Changed

File Change
vlib/db/pg/orm.v u8/i8: t_chart_int2 with hton16
vlib/orm/orm.v Track string default attribute, quote in DDL
vlib/orm/orm_func_test.v Remove "..." workaround
vlib/orm/orm_null_test.v Remove workaround, fix assertion
vlib/orm/orm_upsert_test.v Remove "..." workaround

Tests

All 38 ORM tests pass.

Fix vlang#27986: Map u8 to Oid.t_int2 (smallint) instead of Oid.t_char
in pg_stmt_match, using conv.hton16 for proper byte order conversion.
Previously u8 was bound as PostgreSQL's internal "char" type, causing
type mismatch errors when the column was smallint.

Fix vlang#27987: Properly quote string values in DEFAULT clauses during
DDL generation. Track whether the default came from a string attribute
and wrap with SQL single quotes to avoid invalid SQL like
DEFAULT /dashboard instead of DEFAULT '/dashboard'.

Co-Authored-By: Claude <noreply@anthropic.com>
@medvednikov

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6426f7699e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread vlib/orm/orm.v Outdated
Jengro777 and others added 5 commits July 31, 2026 08:43
Add is_sql_expr() helper to detect SQL function calls (e.g.
gen_random_uuid()) and keyword constants (e.g. CURRENT_TIME,
CURRENT_DATE, CURRENT_TIMESTAMP) so that @[default: 'CURRENT_TIME']
correctly produces DEFAULT CURRENT_TIME rather than DEFAULT
'CURRENT_TIME'.

String literal defaults (e.g. @[default: '/dashboard']) continue
to be properly quoted with single quotes.

Co-Authored-By: Claude <noreply@anthropic.com>
…istic

Replace the all-uppercase heuristic with a clean kind-based strategy:

- .plain kind (bare identifier, e.g. @[default: CURRENT_TIME]) → no quote
- .number kind (e.g. @[default: 42]) → no quote
- .string kind with parentheses (e.g. @[default: 'gen_random_uuid()']) → no quote
- .string kind otherwise (e.g. @[default: '/dashboard']) → quote

This eliminates false positives where uppercase string values like
'YES', 'ACTIVE', or 'NULL' would be incorrectly treated as SQL
expressions. Users who need SQL keyword defaults should use bare
identifiers (without quotes) — which V's attribute parser already
supports as .plain kind.

Updated sqlite_orm_test.v to use bare identifiers for CURRENT_TIME,
CURRENT_DATE, and CURRENT_TIMESTAMP.

Co-Authored-By: Claude <noreply@anthropic.com>
Replace @[default: 'CURRENT_TIMESTAMP'] with @[default: CURRENT_TIMESTAMP]
(bare identifier, .plain kind) so the SQL expression is not quoted.

This aligns with the kind-based approach: .plain = SQL expression (no quote),
.string = string literal (quote).

Covered databases:
- PostgreSQL: CURRENT_TIMESTAMP, gen_random_uuid() (parens detected)
- MySQL: CURRENT_TIMESTAMP
- SQLite: CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP (already updated)

Co-Authored-By: Claude <noreply@anthropic.com>
…xpressions

Update all remaining uses of quoted SQL expression defaults across the
codebase to use bare identifiers (.plain kind):

- vlib/orm/orm_option_time_test.v: CURRENT_TIME
- vlib/v/tests/orm_array_field_test.v: CURRENT_TIME
- vlib/v3/tests/orm_join_sql_attr_test.v: db_default (string literal)
- examples/veb_orm_jwt/user_entities.v: CURRENT_TIMESTAMP (x3)
- examples/veb_fullstack/product_entities.v: CURRENT_TIMESTAMP

Also fix the old manual double-quote workaround in v3 test.

Co-Authored-By: Claude <noreply@anthropic.com>
@Jengro777

Copy link
Copy Markdown
Contributor Author

request for examination

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.

## Bug: V ORM default: attribute strips string quotes, generating invalid SQL ## Bug: V ORM binds u8 as PG "char" instead of smallint

2 participants