MARS-1046: ISO 8601 Date Format Fix for FILE_MANAGER
Overview
This package fixes parsing of ISO 8601 datetime formats with milliseconds and timezone in Oracle FILE_MANAGER external tables. The issue occurs when processing dates like 2012-03-02T14:16:23.798+01:00 where the literal 'T' separator between date and time components must be quoted in Oracle date format strings.
Problem Description
Issue: When configuring date formats in CT_MRDS.A_COLUMN_DATE_FORMAT table with ISO 8601 format containing the 'T' separator, data is not correctly interpreted by external tables.
Example:
- CSV Data:
2012-03-02T14:16:23.798+01:00 - Configured Format:
YYYY-MM-DDTHH24:MI:SS.FF3TZH:TZM❌ (fails) - Required Format:
YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM✅ (works)
Root Cause: Oracle external table FIELD_LIST requires literal characters (like 'T') to be enclosed in double quotes. The configured format in A_COLUMN_DATE_FORMAT table does not include these quotes, causing parsing failures.
Solution
MARS-1046 introduces a private function NORMALIZE_DATE_FORMAT that automatically normalizes date format strings before they are used in external table definitions. This function:
- Detects unquoted 'T' separators in ISO 8601 formats
- Wraps them in double quotes for Oracle compatibility
- Maintains backward compatibility with existing date formats
- Returns original format if normalization fails (safety feature)
Function Logic:
-- Input: 'YYYY-MM-DDTHH24:MI:SS.FF3TZH:TZM'
-- Output: 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
The function is applied automatically in GENERATE_EXTERNAL_TABLE_PARAMS when building FIELD_LIST for DATE/TIMESTAMP columns.
Contents
install_mars1046.sql- Master installation script with SPOOL loggingrollback_mars1046.sql- Master rollback script01_MARS_1046_install_CT_MRDS_FILE_MANAGER_SPEC.sql- Update package specification02_MARS_1046_install_CT_MRDS_FILE_MANAGER_BODY.sql- Update package body91_MARS_1046_rollback_CT_MRDS_FILE_MANAGER_BODY.sql- Rollback package body92_MARS_1046_rollback_CT_MRDS_FILE_MANAGER_SPEC.sql- Rollback package specificationtrack_package_versions.sql- Package version tracking scriptverify_packages_version.sql- Universal package verification scriptFILE_MANAGER.pkg- Updated package specification (v3.3.1)FILE_MANAGER.pkb- Updated package body (v3.3.1)
Prerequisites
- Oracle Database 23ai
- ENV_MANAGER package v3.1.0+
- FILE_MANAGER package v3.3.0 (MARS-1056)
- ADMIN user privileges
Installation
Option 1: Master Script (Recommended)
IMPORTANT: Execute as ADMIN user for proper privilege management.
# Using PowerShell
Get-Content "MARS_Packages/REL02/MARS-1046/install_mars1046.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
# Log file created: INSTALL_MARS_1046_<PDB>_<timestamp>.log
Option 2: Individual Scripts
# IMPORTANT: Execute as ADMIN user
Get-Content "01_MARS_1046_install_CT_MRDS_FILE_MANAGER_SPEC.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
Get-Content "02_MARS_1046_install_CT_MRDS_FILE_MANAGER_BODY.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
Get-Content "track_package_versions.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
Get-Content "verify_packages_version.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
Verification
After installation, verify the changes:
-- Check package version
SELECT FILE_MANAGER.GET_VERSION() FROM DUAL;
-- Expected: 3.3.1
-- Check build info
SELECT FILE_MANAGER.GET_BUILD_INFO() FROM DUAL;
-- Expected: Package: FILE_MANAGER
-- Version: 3.3.1
-- Build Date: 2025-11-27 14:00:00
-- Author: Grzegorz Michalski
-- Verify no untracked changes
SELECT CT_MRDS.ENV_MANAGER.CHECK_PACKAGE_CHANGES('CT_MRDS', 'FILE_MANAGER') FROM DUAL;
-- Expected: OK: Package CT_MRDS.FILE_MANAGER has not changed.
-- Check for compilation errors
SELECT * FROM ALL_ERRORS
WHERE OWNER = 'CT_MRDS'
AND NAME = 'FILE_MANAGER'
ORDER BY SEQUENCE;
-- Expected: No rows returned
Rollback
If rollback is needed, use the master rollback script:
# IMPORTANT: Execute as ADMIN user
Get-Content "MARS_Packages/REL02/MARS-1046/rollback_mars1046.sql" | sql "ADMIN/Cloudpass#34@ggmichalski_high"
# Log file created: ROLLBACK_MARS_1046_<PDB>_<timestamp>.log
This restores FILE_MANAGER to version 3.3.0 (MARS-1056).
Expected Changes
FILE_MANAGER Package:
- Version: 3.3.0 → 3.3.1 (PATCH - Bug fix)
- New private function:
NORMALIZE_DATE_FORMAT - Modified procedure:
GENERATE_EXTERNAL_TABLE_PARAMS - Version history updated with MARS-1046 entry
No schema changes - This is a code-only patch with no database structure modifications.
Testing
Test Scenario: ISO 8601 Date Format with T Separator
1. Configure date format with T separator:
CALL CT_MRDS.FILE_MANAGER.ADD_COLUMN_DATE_FORMAT(
pTemplateTableName => 'CT_ET_TEMPLATES.YOUR_TEMPLATE',
pColumnName => 'YOUR_DATE_COLUMN',
pDateFormat => 'YYYY-MM-DDTHH24:MI:SS.FF3TZH:TZM'
);
2. Create external table:
BEGIN
CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
pTableName => 'YOUR_EXTERNAL_TABLE',
pTemplateTableName => 'CT_ET_TEMPLATES.YOUR_TEMPLATE',
pPrefix => 'INBOX/SOURCE/FILE_ID/TABLE/',
pBucketUri => CT_MRDS.ENV_MANAGER.gvInboxBucketUri,
pFileName => NULL
);
END;
/
3. Verify external table definition:
-- Check generated FIELD_LIST for proper date format
SELECT DBMS_METADATA.GET_DDL('TABLE', 'YOUR_EXTERNAL_TABLE', 'ODS') FROM DUAL;
Expected Result: Date column should have format: DATE 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM' (with quoted T)
4. Test data parsing:
-- Sample data in CSV: 2012-03-02T14:16:23.798+01:00
SELECT YOUR_DATE_COLUMN FROM ODS.YOUR_EXTERNAL_TABLE WHERE ROWNUM <= 10;
Expected Result: Dates are parsed correctly without ORA-01858 errors.
Additional Test Cases
Test Case 1: Standard formats (no change)
- Format:
DD/MM/YYYY HH24:MI:SS - Expected: No normalization applied (backward compatible)
Test Case 2: Other ISO 8601 variants
- Format:
YYYY-MM-DD HH24:MI:SS(space separator) - Expected: Works as before (no T to normalize)
Test Case 3: NULL format
- Format: NULL
- Expected: Falls back to ENV_MANAGER.gvDefaultDateFormat
Known Issues
None currently identified.
Related
- MARS-1056: VARCHAR2 CHAR/BYTE semantics fix
- MARS-1049: CSV encoding support
- Package Deployment Guide:
confluence/Package_Deployment_Guide.md - Copilot Instructions:
.github/copilot-instructions.md
Technical Details
NORMALIZE_DATE_FORMAT Function Signature
FUNCTION NORMALIZE_DATE_FORMAT(pDateFormat IN VARCHAR2)
RETURN VARCHAR2
IS
vNormalizedFormat VARCHAR2(200);
BEGIN
IF pDateFormat IS NULL THEN
RETURN NULL;
END IF;
vNormalizedFormat := pDateFormat;
-- Fix ISO 8601 'T' separator
IF INSTR(vNormalizedFormat, '"T"') = 0 AND REGEXP_LIKE(vNormalizedFormat, '[YMD]T[HM]') THEN
vNormalizedFormat := REGEXP_REPLACE(vNormalizedFormat, '([YMD])T([HM])', '\\1"T"\\2');
END IF;
RETURN vNormalizedFormat;
EXCEPTION
WHEN OTHERS THEN
RETURN pDateFormat; -- Safety: return original on error
END NORMALIZE_DATE_FORMAT;
Integration Point
Modified in GENERATE_EXTERNAL_TABLE_PARAMS:
-- Before (MARS-1056):
rec.quoted_column_name || ' DATE ' || CHR(39) || GET_DATE_FORMAT(...) || CHR(39)
-- After (MARS-1046):
rec.quoted_column_name || ' DATE ' || CHR(39) || NORMALIZE_DATE_FORMAT(GET_DATE_FORMAT(...)) || CHR(39)
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2025-11-27 | Initial release - ISO 8601 T separator fix |
Support
For questions or issues:
- Check verification queries above
- Review process logs:
SELECT * FROM CT_MRDS.A_PROCESS_LOG WHERE LOG_TIMESTAMP > SYSDATE - 1 ORDER BY LOG_TIMESTAMP DESC; - Check package documentation:
SELECT GET_PACKAGE_DOCUMENTATION('FILE_MANAGER', 'CT_MRDS') FROM DUAL; - Contact: Grzegorz Michalski
Last Updated: 2025-11-27
Package Version: FILE_MANAGER 3.3.1
MARS Issue: MARS-1046