The Legacy Obituaries

Case q04 · fact

Our app relies on empty string being NULL in VARCHAR2 columns. Which Azure targets keep that behaviour?

Expected: None of Azure SQL DB/MI or PostgreSQL treat '' as NULL; flags this as a semantic difference requiring code review; Oracle Database@Azure keeps Oracle semantics.

The dataset had no mapping from empty-string-equals-NULL to Oracle Database@Azure. The mapping was added and the question re-run. The re-run is shown at the bottom; the frozen totals are not updated.

No tools

The model alone, answering from memory.
larger model · 1 turn · 21 s · 16.5k in / 2.0k out

✓ verdict ✗ grounded ✗ cited

Grader: Correct verdict; many uncited specifics like edb_redwood_strings and LENGTH

Answer

Only Azure targets that actually run Oracle Database keep '' = NULL: Oracle Database@Azure (Exadata or Autonomous) and Oracle on Azure VMs. Azure SQL Database, Azure SQL Managed Instance, SQL Server on a VM and Azure Database for PostgreSQL all treat '' as a real value that is not NULL. None of them has a setting to change that.

Target '' becomes NULL? Notes
Oracle Database@Azure (Exadata Database Service, Autonomous Database) ✅ Yes Real Oracle running in Azure datacenters. Same behaviour, including 23ai. https://learn.microsoft.com/azure/oracle/oracle-db/database-overview
Oracle on Azure VMs (you manage it) ✅ Yes Same engine, so the same behaviour. https://learn.microsoft.com/azure/virtual-machines/workloads/oracle/oracle-overview
Azure SQL Database / Managed Instance / SQL Server on a VM ❌ No '' and NULL are different values. ANSI_NULLS and CONCAT_NULL_YIELDS_NULL don't change this.
Azure Database for PostgreSQL – Flexible Server ❌ No Standard PostgreSQL behaviour. The orafce extension adds Oracle-style functions but doesn't change how '' is stored. https://www.postgresql.org/docs/current/functions-comparison.html
EDB Postgres Advanced Server (on a VM or EDB's managed service) ❌ No, as far as I know Its Oracle-compatibility settings (e.g. edb_redwood_strings) change how NULL behaves in || concatenation. I don't believe any of them turn stored '' into NULL. Test it before relying on it.

Where things break if you move to SQL Server or PostgreSQL:

  • WHERE col IS NULL stops finding rows that were written as ''. The same applies to NVL/COALESCE, and to NOT NULL constraints, which will now accept ''.
  • Length: LENGTH('') returns NULL in Oracle but 0 in PostgreSQL. SQL Server's LEN('') also returns 0.
  • Concatenation: NULL || 'x' gives 'x' in Oracle but NULL in PostgreSQL. In SQL Server, + gives NULL by default. CONCAT() treats NULL as empty on both.
  • Application and ORM code that sends '' expecting it to be stored as NULL (common with JDBC and .NET binds).
  • Migration tools: Microsoft's SQL Server Migration Assistant (SSMA) and ora2pg (for PostgreSQL) convert the schema and code, but they won't rewrite this logic for you. Your existing data is fine, because Oracle never stored '' in the first place. The risk is new rows written after cutover.

How to handle it if you still move to SQL Server or PostgreSQL:

  1. Add a BEFORE INSERT/UPDATE trigger (on SQL Server, an INSTEAD OF trigger) that sets col = NULLIF(col, ''). Or do the same conversion in the data-access layer, which scales better.
  2. Add CHECK (col <> '') constraints so any '' that slips through fails loudly.
  3. Search the code for IS NULL, NVL, LENGTH, || and DECODE on string columns, and add regression tests for the '' cases.

Recommendation: if this behaviour runs throughout the app and you don't want to refactor, go with Oracle Database@Azure or Oracle on VMs. If you're moving off Oracle to cut licence costs, treat ''-vs-NULL as a separate workstream with its own tests. It's one of the most common reasons these migrations go wrong after cutover.

Keyword search

BM25 over the same 446 documents: top 8 passages pasted in, one pass, references not followed.
larger model · 1 turn · 14 s · 18.8k in / 1.3k out

✗ verdict ✓ grounded ✗ cited

Grader: Headline 'none'; only hedges on Oracle Database@Azure with 'presumably'

8 keyword-search passages
  1. caveat_empty-string-sqlserver-not-null score 28.686
  2. feature_empty-string-null score 22.67
  3. mapping_empty-string-null--azure-pg-flex score 20.166
  4. mapping_empty-string-null--azure-sql-db score 19.12
  5. source_orafce-readme score 16.265
  6. target_ora2pg score 15.56
  7. mapping_varchar2-byte-semantics--azure-pg-flex score 14.356
  8. caveat_empty-string-postgres-not-null score 13.349
Answer

Verdict: None of the Azure targets these passages cover treats '' as NULL natively. Azure SQL / SQL Server and Azure Database for PostgreSQL Flexible Server both keep an empty string as a real value, separate from NULL. You can get Oracle's behaviour back on either one, but only by changing code or data.

Azure SQL Database and SQL Server-family targets [1][4]

  • An empty string is stored as a zero-length value. Microsoft's documentation says a null value is different from an empty or zero value.
  • What changes after migration:
    • Inserting '' now stores a non-null row.
    • IS NULL no longer matches those rows.
    • NOT NULL columns now accept '', where Oracle rejected it.
  • How to work around it:
    • Pick one policy: either convert '' to NULL when writing (in the application or a trigger), or use NULLIF in queries to treat the two as the same.
    • Add CHECK constraints or triggers that reject '' on columns where Oracle's NOT NULL used to do that.
    • Turn on SSMA's ISNULL-in-concatenation option.
    • Review every = '' and <> '' comparison. In Oracle these were never true, so they now behave differently.

Azure Database for PostgreSQL Flexible Server [3][8]

  • PostgreSQL separates '' from NULL in the same way SQL Server does. You have two options:
    • Ora2Pg NULL_EQUAL_EMPTY: rewrites IS NULL and IS NOT NULL tests into coalesce()-based checks so the converted code behaves like Oracle [6].
    • Convert the data when it's written: use orafce's replace_empty_strings trigger or an application rule. Ora2Pg's documentation recommends this if you can change the application.
  • Rewrite NVL(col,'x') as coalesce(nullif(col,''),'x'), and test NOT NULL columns.
  • orafce's varchar2 type only changes length counting to bytes. It does not make '' behave as NULL, and orafce's own README says empty strings differ from NULL in PostgreSQL [5][7].

Two more points

  • Oracle itself says applications shouldn't depend on this behaviour and that it may change in future releases. It is still unchanged as of 26ai [2]. Every empty-string literal and every IS NULL test on a character column needs review, whichever target you pick.
  • These passages don't cover running Oracle Database itself on Azure (for example Oracle Database@Azure or Oracle on Azure VMs). I can't confirm from them which targets would keep the behaviour unchanged, although running Oracle itself presumably would.

Sources: orafce README, https://github.com/orafce/orafce/blob/master/README.asciidoc. The other passages [1]–[4] and [6]–[8] came without URLs.

Sanity Context · GROQ

The agent with the GROQ endpoint: schema, joins, Portable Text.
smaller model · 6 turns · 31 s · 35.5k in / 2.5k out

✗ verdict ✓ grounded ✗ cited

Grader: Headline 'none'; Oracle@Azure only hedged with 'presumably'

5 tool calls
  1. initial_context on groq · 4,126 chars back
  2. groq_query on groq · 3,384 chars back
    *[_type=="oracleFeature" && (name match "*empty*" || name match "*null*" || name match "*NULL*" || name match "*VARCHAR*")]{_id, name, slug, category, summary}
  3. groq_query on groq · 358 chars back
    *[_type=="glossary" && (term match "*empty*" || term match "*null*" || term match "*NULL*")]{_id, term, definition, alsoKnownAs}
  4. groq_query on groq · 4,092 chars back
    *[_type=="mapping" && oracleFeature._ref=="feature_empty-string-null"]{
      _id, fidelity, effort, rationale, appliesToOracleVersions,
      "azureTarget": azureTarget->{name, slug, service},
      "sources": sources[]->{title, url},
      "caveats": *[_type=="caveat" && references(^._id)]{
        severity, statement, appliesTo, firsthand,
        "evidence": evidence->{title, url, publisher}
      }
    }
  5. groq_query on groq · 761 chars back
    *[_type=="dispute" && (claimA->mapping->oracleFeature._ref=="feature_empty-string-null" || claimB->mapping->oracleFeature._ref=="feature_empty-string-null")]{
      title, whatDisagrees, resolution,
      "claimA": claimA->{statement, "evidence": evidence->{title,url,publisher}},
      "claimB": claimB->{statement, "evidence": evidence->{title,url,publisher}},
      "resolvedBy": resolvedBy->{title,url}
    }
Answer

Verdict: None. The dataset shows no Azure target that preserves Oracle's "empty string = NULL" behavior for VARCHAR2 natively — only workarounds exist for the two mapped targets.

Feature

Empty string equals NULL — "Oracle treats a character value of zero length as NULL... Oracle's SQL reference explicitly says this may not remain true in future releases and advises applications not to depend on it." Documented, unchanged as of 26ai, applies to Oracle 11.2–26ai.

Mapped Azure targets (both fidelity = workaround)

Azure SQL Database

  • Fidelity: workaround, Effort: M
  • "Oracle stores a zero-length VARCHAR2 as NULL... SQL Server keeps '' as a real value distinct from NULL... After migration the same INSERT of '' produces a non-null row, IS NULL predicates stop matching it, and NOT NULL constraints that used to reject '' now accept it." — NULL and UNKNOWN (Transact-SQL) (Microsoft)
  • Caveat (major): "In SQL Server and Azure SQL an empty string '' is a stored zero-length value that is distinct from NULL." — same source.
  • Applies to Oracle 11.2–26ai.

Azure Database for PostgreSQL Flexible Server

  • Fidelity: workaround, Effort: M
  • "PostgreSQL distinguishes '' from NULL exactly as SQL Server does. Ora2Pg offers NULL_EQUAL_EMPTY, which rewrites IS NULL and IS NOT NULL tests into coalesce()-based checks so converted code keeps Oracle's behaviour... orafce adds a trigger function that replaces empty strings with NULL on write." — Ora2Pg documentation (community), orafce README
  • Caveat (major): "PostgreSQL treats '' as a non-NULL value." — same Ora2Pg source.
  • Applies to Oracle 11.2–26ai.

Gaps

  • No dispute is recorded on this feature.
  • The dataset has no mapping entry for this feature against Oracle Database@Azure or Oracle on Azure VM (both run real Oracle, which would presumably preserve the behavior natively) — the dataset has no evidence either way for those targets.
  • No other azureTarget (Azure SQL Managed Instance, Fabric, etc.) has a mapping for this feature in the dataset.

Bottom line for your app: if you move VARCHAR2-empty-string-as-NULL logic to Azure SQL Database or Azure PostgreSQL Flexible Server, the native behavior does not carry over — you need the cited workarounds (application-level coalesce rewrites, Ora2Pg's NULL_EQUAL_EMPTY, or orafce's empty-to-NULL trigger). No mapped target reproduces the behavior with exact fidelity per this dataset.

GROQ + Knowledge Base

The agent with both endpoints.
smaller model · 7 turns · 63 s · 64.8k in / 2.6k out

✗ verdict ✓ grounded ✓ cited

Grader: Correct on SQL and PostgreSQL; won't answer for Oracle@Azure

6 tool calls
  1. initial_context on groq · 4,126 chars back
  2. initial_context on kb · 7,679 chars back
  3. groq_query on groq · 3,360 chars back
    *[_type=="oracleFeature" && (name match "*empty*" || name match "*NULL*" || name match "*VARCHAR2*")]{_id, name, slug, category, summary}
  4. groq_query on groq · 4,018 chars back
    *[_type=="mapping" && oracleFeature._ref=="feature_empty-string-null"]{
      _id, fidelity, effort, rationale, appliesToOracleVersions,
      "azureTarget": azureTarget->{name, slug, service},
      "sources": sources[]->{title, url},
      "caveats": *[_type=="caveat" && references(^._id)]{
        severity, statement, appliesTo, firsthand,
        "evidence": evidence->{title, url}
      }
    }
  5. groq_query on groq · 1,081 chars back
    *[_type=="oracleFeature" && slug.current=="empty-string-null"]{
      "sources": sources[]->{title, url},
      "disputes": *[_type=="dispute" && (claimA->mapping->oracleFeature._ref==^._id || claimB->mapping->oracleFeature._ref==^._id)]{title, whatDisagrees, resolution, "claimA": claimA->{statement, "evidence": evidence->{title,url}}, "claimB": claimB->{statement, "evidence": evidence->{title,url}}, "resolvedBy": resolvedBy->{title,url}}
    }
  6. knowledge_base_read on kb · 2,832 chars back
    {
     "knowledgeBase": "kb6MdvV3ZA3Q",
     "paths": [
      "oracle_concepts/terminology"
     ]
    }
Answer

Verdict: None of the mapped Azure targets preserve Oracle's "empty string = NULL" behaviour natively. The dataset records this as a "workaround" (i.e., no native equivalent — must be rebuilt via extra logic) for both targets it covers, and has no mapping entry at all for the other Azure targets (Azure SQL Managed Instance, Oracle Database@Azure, Oracle on Azure VMs).

Scoped facts — Oracle feature: Empty string equals NULL (Nulls (SQL Language Reference 19c)), applies to Oracle 11.2 through 26ai (long-standing, undeprecated, but Oracle itself warns not to rely on it).

  • Azure SQL Database — fidelity workaround, effort M. "Oracle stores a zero-length VARCHAR2 as NULL... SQL Server keeps '' as a real value distinct from NULL... After migration the same INSERT of '' produces a non-null row, IS NULL predicates stop matching it, and NOT NULL constraints that used to reject '' now accept it." — NULL and UNKNOWN (Transact-SQL), SSMA for Oracle: Project Settings (Conversion). Caveat (major): "In SQL Server and Azure SQL an empty string '' is a stored zero-length value that is distinct from NULL" — Microsoft's NULL documentation states a null value is different from an empty or zero value.

  • Azure Database for PostgreSQL Flexible Server — fidelity workaround, effort M. "PostgreSQL distinguishes '' from NULL exactly as SQL Server does." Ora2Pg's NULL_EQUAL_EMPTY directive can rewrite IS NULL/IS NOT NULL tests into coalesce()-based checks to reproduce Oracle's behaviour, though Ora2Pg's own docs recommend instead converting empty strings to NULL if the application can be changed; orafce offers a trigger to replace empty strings with NULL on write. — Ora2Pg documentation, orafce README. Caveat (major): "PostgreSQL treats '' as a non-NULL value" — same sources.

Gap: The dataset has no mapping or caveat entry for this feature against Azure SQL Managed Instance, Oracle Database@Azure, or Oracle on Azure VMs. I can't say whether those preserve the behaviour — no evidence either way in this dataset. (Note: no dispute record touches this feature either.)

Practical implication: since fidelity is "workaround" rather than "exact" or "partial" on both covered targets, keeping the empty-string-is-NULL behaviour is not automatic on either — it requires explicit rewriting of IS NULL checks, coalesce-style logic, or trigger-based normalization, per the citations above.

After the fix

No tools

The model alone, answering from memory.
larger model · 1 turn · 21 s · 16.5k in / 2.0k out

✓ verdict ✗ grounded ✗ cited

Grader: Correct verdict; EDB, LENGTH, 23ai and VM claims unsupported

Answer

Only Azure targets that actually run Oracle Database keep '' = NULL: Oracle Database@Azure (Exadata or Autonomous) and Oracle on Azure VMs. Azure SQL Database, Azure SQL Managed Instance, SQL Server on a VM and Azure Database for PostgreSQL all treat '' as a real value that is not NULL. None of them has a setting to change that.

Target '' becomes NULL? Notes
Oracle Database@Azure (Exadata Database Service, Autonomous Database) ✅ Yes Real Oracle running in Azure datacenters. Same behaviour, including 23ai. https://learn.microsoft.com/azure/oracle/oracle-db/database-overview
Oracle on Azure VMs (you manage it) ✅ Yes Same engine, so the same behaviour. https://learn.microsoft.com/azure/virtual-machines/workloads/oracle/oracle-overview
Azure SQL Database / Managed Instance / SQL Server on a VM ❌ No '' and NULL are different values. ANSI_NULLS and CONCAT_NULL_YIELDS_NULL don't change this.
Azure Database for PostgreSQL – Flexible Server ❌ No Standard PostgreSQL behaviour. The orafce extension adds Oracle-style functions but doesn't change how '' is stored. https://www.postgresql.org/docs/current/functions-comparison.html
EDB Postgres Advanced Server (on a VM or EDB's managed service) ❌ No, as far as I know Its Oracle-compatibility settings (e.g. edb_redwood_strings) change how NULL behaves in || concatenation. I don't believe any of them turn stored '' into NULL. Test it before relying on it.

Where things break if you move to SQL Server or PostgreSQL:

  • WHERE col IS NULL stops finding rows that were written as ''. The same applies to NVL/COALESCE, and to NOT NULL constraints, which will now accept ''.
  • Length: LENGTH('') returns NULL in Oracle but 0 in PostgreSQL. SQL Server's LEN('') also returns 0.
  • Concatenation: NULL || 'x' gives 'x' in Oracle but NULL in PostgreSQL. In SQL Server, + gives NULL by default. CONCAT() treats NULL as empty on both.
  • Application and ORM code that sends '' expecting it to be stored as NULL (common with JDBC and .NET binds).
  • Migration tools: Microsoft's SQL Server Migration Assistant (SSMA) and ora2pg (for PostgreSQL) convert the schema and code, but they won't rewrite this logic for you. Your existing data is fine, because Oracle never stored '' in the first place. The risk is new rows written after cutover.

How to handle it if you still move to SQL Server or PostgreSQL:

  1. Add a BEFORE INSERT/UPDATE trigger (on SQL Server, an INSTEAD OF trigger) that sets col = NULLIF(col, ''). Or do the same conversion in the data-access layer, which scales better.
  2. Add CHECK (col <> '') constraints so any '' that slips through fails loudly.
  3. Search the code for IS NULL, NVL, LENGTH, || and DECODE on string columns, and add regression tests for the '' cases.

Recommendation: if this behaviour runs throughout the app and you don't want to refactor, go with Oracle Database@Azure or Oracle on VMs. If you're moving off Oracle to cut licence costs, treat ''-vs-NULL as a separate workstream with its own tests. It's one of the most common reasons these migrations go wrong after cutover.

Keyword search

BM25 over the same 446 documents: top 8 passages pasted in, one pass, references not followed.
larger model · 1 turn · 12 s · 18.9k in / 1.2k out

✓ verdict ✓ grounded ✗ cited

Grader: Correct: only DB@Azure keeps it; SQL/PG workarounds, grounded

8 keyword-search passages
  1. caveat_empty-string-sqlserver-not-null score 28.556
  2. feature_empty-string-null score 22.551
  3. mapping_empty-string-null--azure-pg-flex score 19.939
  4. mapping_empty-string-null--azure-sql-db score 18.932
  5. mapping_empty-string-null--oracle-db-at-azure score 18.127
  6. source_orafce-readme score 16.099
  7. target_ora2pg score 15.422
  8. mapping_varchar2-byte-semantics--azure-pg-flex score 14.135
Answer

Only Oracle Database@Azure keeps this behaviour. Azure SQL and Azure Database for PostgreSQL Flexible Server both treat '' and NULL as different values, so you'd need workarounds on either.

Oracle Database@Azure: works as-is [5]

  • You still run Oracle Database (Exadata Database Service, Base Database Service or Autonomous Database), just in Azure datacenters. An empty VARCHAR2 is still stored and compared as NULL.
  • Your existing NULL-handling code doesn't need rewriting.
  • Record this dependency in your migration inventory. A later move to Azure SQL or PostgreSQL would bring the problem back.

Azure SQL Database (and Azure SQL generally): behaviour changes [1][4]

  • '' is stored as a real zero-length value, not NULL. Microsoft's docs say a null value is different from an empty or zero value.
  • What breaks:
    • Inserting '' now creates a non-null row.
    • IS NULL no longer matches those rows.
    • NOT NULL columns now accept ''.
    • = '' and <> '' comparisons, which never matched in Oracle, start matching.
  • Fixes:
    • Choose one policy: either convert '' to NULL when writing (in the app or a trigger), or treat them as equal in queries with NULLIF.
    • Add CHECK constraints or triggers that reject '' where NOT NULL used to block it.
    • Turn on SSMA's ISNULL-in-concatenation option so NULL || 'x' gives the same result as in Oracle.

Azure Database for PostgreSQL Flexible Server: behaviour changes [3][6][7]

  • PostgreSQL also treats '' and NULL as different.
  • Fixes (estimated as medium effort):
    • Ora2Pg NULL_EQUAL_EMPTY: rewrites IS NULL and IS NOT NULL tests into coalesce() checks. Ora2Pg's documentation recommends converting empty strings to NULL instead, if you can change the application.
    • orafce trigger: its replace_empty_strings trigger turns '' into NULL on write. Installing orafce alone doesn't fix this; its README says empty strings still differ from NULL in PostgreSQL.
    • Rewrite NVL(col,'x') as coalesce(nullif(col,''),'x'), and test NOT NULL columns.

Longer-term caveat [2][5] Oracle has behaved this way through 26ai, but its SQL reference warns this may change in future releases and tells applications not to rely on it. Even on Oracle Database@Azure, plan to review empty-string literals and IS NULL tests on character columns eventually.

Sources:

Sanity Context · GROQ

The agent with the GROQ endpoint: schema, joins, Portable Text.
smaller model · 4 turns · 29 s · 32.6k in / 1.7k out

✓ verdict ✓ grounded ✓ cited

Grader: Correct verdict with workarounds; grounded; code review only implied

3 tool calls
  1. initial_context on groq · 4,126 chars back
  2. groq_query on groq · 614 chars back
    *[_type=="oracleFeature" && (name match "*empty*" || name match "*NULL*" || name match "*VARCHAR*")]{_id, name, "slug": slug.current, category}
  3. groq_query on groq · 5,738 chars back
    *[_type=="oracleFeature" && slug.current=="empty-string-null"][0]{
      _id, name, category, introducedIn, deprecatedIn, desupportedIn, oracleReplacement,
      "sources": sources[]->{title, url, publisher},
      "mappings": *[_type=="mapping" && oracleFeature._ref==^._id]{
        _id, fidelity, effort, rationale, appliesToOracleVersions,
        "azureTarget": azureTarget->{name, "slug": slug.current, service},
        "sources": sources[]->{title, url},
        "caveats": *[_type=="caveat" && mapping._ref==^._id]{
          _id, severity, statement, appliesTo, firsthand,
          "evidence": evidence->{title, url, publisher}
        }
      }
    }
Answer

Verdict: Only Oracle Database@Azure preserves Oracle's "empty string = NULL" behaviour exactly. Azure SQL Database and Azure Database for PostgreSQL Flexible Server do not — they treat '' as a real, non-NULL value, requiring workarounds.

Scope: Oracle 11.2 through 26ai, all Oracle editions covered by this feature (Empty string equals NULL, introduced pre-11.2, not deprecated/desupported).

Azure targets, by fidelity

  • Oracle Database@Azure — fidelity: exact, effort S. Runs Oracle Database itself (Exadata Database Service, Base Database Service, or Autonomous Database) inside Azure datacenters, so SQL semantics are unchanged: a zero-length VARCHAR2 is still stored and compared as NULL. No caveats recorded. — Overview: Oracle Database@Azure, Nulls (SQL Language Reference 19c)

  • Azure SQL Database — fidelity: workaround, effort M. SQL Server/Azure SQL stores '' as a distinct, non-null zero-length value. After migration, an INSERT of '' produces a non-null row, IS NULL predicates stop matching it, and NOT NULL constraints that used to reject '' now accept it — Major caveat: "a null value is different from an empty or zero value." — NULL and UNKNOWN (Transact-SQL), SSMA for Oracle: Project Settings (Conversion)

  • Azure Database for PostgreSQL Flexible Server — fidelity: workaround, effort M. PostgreSQL also distinguishes '' from NULL. Major caveat notes Ora2Pg's NULL_EQUAL_EMPTY directive rewrites IS NULL/IS NOT NULL tests into coalesce()-based checks to preserve Oracle's behaviour, though Ora2Pg's own docs recommend instead converting empty strings to NULL in the application where feasible; the orafce extension offers a trigger to replace '' with NULL on write. — Ora2Pg documentation, orafce README

No dispute is recorded on this feature in the dataset.

Gap: No mapping exists in this dataset for other Azure targets (e.g., Oracle on Azure VM, Azure SQL Managed Instance) regarding this specific behavior — only the three above are covered for the "empty-string-null" feature.

GROQ + Knowledge Base

The agent with both endpoints.
smaller model · 5 turns · 28 s · 57.7k in / 2.5k out

✓ verdict ✓ grounded ✓ cited

Grader: Correct verdict, flags code review; MI gap noted honestly

4 tool calls
  1. initial_context on groq · 4,126 chars back
  2. initial_context on kb · 7,679 chars back
  3. groq_query on groq · 17,141 chars back
    *[_type=="oracleFeature" && (name match "*empty*" || name match "*NULL*" || name match "*VARCHAR2*" || category=="datatype")]{_id, name, "slug": slug.current, category, summary}
  4. groq_query on groq · 5,233 chars back
    *[_type=="mapping" && oracleFeature._ref=="feature_empty-string-null"]{
      _id, fidelity, effort, rationale, appliesToOracleVersions,
      "azureTarget": azureTarget->{name, "slug": slug.current},
      "sources": sources[]->{title, url},
      "caveats": *[_type=="caveat" && references(^._id)]{severity, statement, appliesTo, firsthand, "evidence": evidence->{title, url}, "disputes": *[_type=="dispute" && (claimA._ref==^._id || claimB._ref==^._id)]{title, whatDisagrees, resolution, "claimA": claimA->{statement}, "claimB": claimB->{statement}, "resolvedBy": resolvedBy->{title,url}}}
    }
Answer

Verdict: Only Oracle Database@Azure preserves Oracle's "empty string = NULL" behavior exactly. Azure SQL Database and Azure Database for PostgreSQL – Flexible Server do NOT preserve it natively — both require a workaround. The dataset has no mapping for Azure SQL Managed Instance or Oracle on Azure VMs for this feature.

Oracle feature

Empty string equals NULL — "Oracle treats a character value of zero length as NULL... Oracle's SQL reference explicitly says this may not remain true in future releases and advises applications not to depend on it." Applies to Oracle 11.2 through 26ai; long-standing and unchanged, documented but not guaranteed. [Empty string equals NULL feature summary] (source not URL-bearing itself; see per-target citations below).

Azure targets, by fidelity

Oracle Database@Azure — fidelity: exact, effort: S "Oracle Database@Azure runs Oracle Database itself (Exadata Database Service, Base Database Service or Autonomous Database) inside Azure datacenters, so SQL semantics are unchanged and a zero-length VARCHAR2 is still stored and compared as NULL. The behaviour moves with the database; only a later move to a non-Oracle engine reintroduces the difference." No caveats recorded. Sources: Overview: Oracle Database@Azure, Nulls (SQL Language Reference 19c) Applies to Oracle 11.2–26ai.

Azure SQL Database — fidelity: workaround, effort: M "SQL Server keeps '' as a real value distinct from NULL... After migration the same INSERT of '' produces a non-null row, IS NULL predicates stop matching it, and NOT NULL constraints that used to reject '' now accept it, so data and code need explicit handling." Caveat (major): "In SQL Server and Azure SQL an empty string '' is a stored zero-length value that is distinct from NULL; Microsoft's NULL documentation states that a null value is different from an empty or zero value, so Oracle code that relied on '' being NULL changes behaviour." Evidence: NULL and UNKNOWN (Transact-SQL) Sources: also SSMA for Oracle: Project Settings (Conversion) Applies to Oracle 11.2–26ai.

Azure Database for PostgreSQL Flexible Server — fidelity: workaround, effort: M "PostgreSQL distinguishes '' from NULL exactly as SQL Server does. Ora2Pg offers NULL_EQUAL_EMPTY, which rewrites IS NULL and IS NOT NULL tests into coalesce()-based checks so converted code keeps Oracle's behaviour... orafce adds a trigger function that replaces empty strings with NULL on write." Caveat (major): "PostgreSQL treats '' as a non-NULL value; Ora2Pg's NULL_EQUAL_EMPTY directive exists to rewrite IS NULL tests into coalesce()-based checks precisely because PostgreSQL differentiates empty strings from NULL, and its documentation recommends converting empty strings to NULL when the application can be changed." Evidence: Ora2Pg documentation (configuration directives) Sources: also orafce README Applies to Oracle 11.2–26ai.

Gaps

  • No mapping in the dataset for Azure SQL Managed Instance or Oracle on Azure VMs (Azure VM would presumably inherit Oracle semantics since it's the same engine, but this is not stated in any retrieved document — I won't assume it).
  • No dispute entries touch this feature.

Bottom line for your app: if you must keep '' == NULL semantics without code changes, Oracle Database@Azure is the only target with exact fidelity in this dataset. Azure SQL Database or PostgreSQL Flexible Server require workaround tooling (SSMA conversion settings / Ora2Pg's NULL_EQUAL_EMPTY or orafce triggers) and code review of every empty-string literal and IS NULL test.

← q03All casesq05 →