# AGGREGATED_ALLOTMENT External Tables - Rozwiązanie problemów

## 🔍 Diagnoza problemów

### Problem który napotkałeś:
```sql
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
-- ORA-29913: error while processing ODCIEXTTABLEOPEN routine
-- ORA-20401: Authorization failed
```

### Przyczyny problemów:

#### 1. **Brak uprawnień do external tables**
- External tables zostały utworzone w schemacie **ODS**
- Próbujesz dostępu z schematu **CT_MRDS** 
- Brak uprawnień SELECT na ODS.TOP_AGGREGATED_ALLOTMENT_*

#### 2. **Niepoprawna konfiguracja ARCHIVE table**
- **Użyty prefix:** `ARCHIVE/TOP/AGGREGATED_ALLOTMENT`
- **Faktyczne pliki:** `TOP/AGGREGATED_ALLOTMENT/YEAR=2025/MONTH=08/*.parquet`
- **Problem:** PARQUET files z Hive partitioning wymagają specjalnej konfiguracji

#### 3. **Weryfikacja plików** ✅
```bash
# ODS bucket - pliki CSV istnieją
oci os object list --bucket-name data --prefix "ODS/TOP/AGGREGATED_ALLOTMENT/"
# ✅ 14 plików CSV

# ARCHIVE bucket - pliki PARQUET z partycjonowaniem Hive
oci os object list --bucket-name history --prefix "ARCHIVE/TOP/AGGREGATED_ALLOTMENT/"
# ❌ Brak plików w tej lokalizacji

oci os object list --bucket-name history --prefix "TOP/AGGREGATED_ALLOTMENT/"
# ✅ 8 plików PARQUET w strukturze YEAR=2025/MONTH=08/
```

## 🔧 Rozwiązania

### Rozwiązanie 1: Nadanie uprawnień

```sql
-- Jako ODS user lub ADMIN
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS;
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS;
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS;

-- Test z CT_MRDS
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;
```

### Rozwiązanie 2: Poprawa konfiguracji ARCHIVE table

```sql
-- Jako ODS user
DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE;

-- Poprawne utworzenie z właściwym prefixem
BEGIN
    FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
        pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
        pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
        pPrefix => 'TOP/AGGREGATED_ALLOTMENT',  -- Bez "ARCHIVE/" prefix
        pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
    );
END;
/
```

### Rozwiązanie 3: Alternatywne podejście - tworzenie w CT_MRDS

```sql
-- Jako CT_MRDS user - utwórz external tables w swoim schemacie
BEGIN
    CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
        pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS_CT',
        pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
        pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT',
        pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri
    );
END;
/

BEGIN
    CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE(
        pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE_CT',
        pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
        pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
        pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
    );
END;
/
```

## 🧪 Testowanie rozwiązań

### Test 1: Weryfikacja external locations
```sql
SELECT table_name, location 
FROM all_external_locations 
WHERE table_name LIKE '%TOP_AGGREGATED_ALLOTMENT%' 
  AND owner IN ('ODS', 'CT_MRDS')
ORDER BY owner, table_name;
```

### Test 2: Próba dostępu do danych
```sql
-- Test ODS (pliki CSV)
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS;

-- Test pierwszych 5 rekordów
SELECT * FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS WHERE ROWNUM <= 5;
```

### Test 3: Weryfikacja ARCHIVE (pliki PARQUET)
```sql
-- Test ARCHIVE (pliki PARQUET z partycjonowaniem)
SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE;

-- Sprawdzenie partycji
SELECT DISTINCT year, month 
FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE 
ORDER BY year, month;
```

## 📊 Struktura plików w buckets

### Data bucket (ODS) - format CSV
```
data/
└── ODS/
    └── TOP/
        └── AGGREGATED_ALLOTMENT/
            ├── AGGREGATED_ALLOTMENT_202508_1_*.csv
            ├── AGGREGATED_ALLOTMENT_202508_2_*.csv
            ├── AGGREGATED_ALLOTMENT_202509_1_*.csv
            └── ... (14 plików CSV)
```

### History bucket (ARCHIVE) - format PARQUET z partycjonowaniem Hive
```
history/
└── TOP/
    └── AGGREGATED_ALLOTMENT/
        └── YEAR=2025/
            ├── MONTH=08/
            │   ├── 202508_1_*.parquet
            │   ├── 202508_2_*.parquet
            │   ├── 202508_3_*.parquet
            │   └── 202508_4_*.parquet
            └── MONTH=09/
                ├── 202509_1_*.parquet
                ├── 202509_2_*.parquet
                ├── 202509_3_*.parquet
                └── 202509_4_*.parquet
```

## ⚠️ Uwagi dotyczące FILE_MANAGER

### Automatyczna detekcja formatu
Pakiet `FILE_MANAGER.CREATE_EXTERNAL_TABLE` automatycznie wykrywa format na podstawie `pBucketUri`:

- **Jeśli** `pBucketUri` zawiera `gvArchiveBucketUri` → format PARQUET z partycjonowaniem Hive
- **Jeśli** `pBucketUri` zawiera `gvDataBucketUri` lub `gvInboxBucketUri` → format CSV

### Konfiguracja środowiska
```sql
-- Sprawdzenie konfiguracji ENV_MANAGER
SET SERVEROUTPUT ON;
DECLARE
  v_inbox VARCHAR2(4000);
  v_data VARCHAR2(4000);
  v_history VARCHAR2(4000);
BEGIN
  v_inbox := CT_MRDS.ENV_MANAGER.gvInboxBucketUri;
  v_data := CT_MRDS.ENV_MANAGER.gvDataBucketUri;
  v_history := CT_MRDS.ENV_MANAGER.gvArchiveBucketUri;
  DBMS_OUTPUT.PUT_LINE('Inbox: ' || v_inbox);
  DBMS_OUTPUT.PUT_LINE('Data: ' || v_data);
  DBMS_OUTPUT.PUT_LINE('History: ' || v_history);
END;
/
```

## 🎯 Zalecane działania

### Krok 1: Nadaj uprawnienia (NAJSZYBSZE)
```sql
-- Jako ADMIN lub z uprawnieniami GRANT
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS;
GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS;
```

### Krok 2: Przebuduj ARCHIVE table
```sql
-- Jako ODS user
DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE;

BEGIN
    FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE(
        pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE',
        pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT',
        pPrefix => 'TOP/AGGREGATED_ALLOTMENT',
        pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri
    );
END;
/

-- Nadaj uprawnienia
GRANT SELECT ON TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS;
```

### Krok 3: Test końcowy
```sql
-- Z schematu CT_MRDS
SELECT 'ODS' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS
UNION ALL
SELECT 'ARCHIVE' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE;
```

Teraz external tables powinny działać poprawnie! 🎉
