
Alibabacloud Odps Information Schema
- 57 installs
- 208 repo stars
- Updated August 4, 2026
- aliyun/alibabacloud-aiops-skills
alibabacloud-odps-information-schema is a Claude skill that converts natural language into SQL against MaxCompute (ODPS) Information Schema metadata views for storage, cost, permission, and governance analysis.
About
This skill converts natural language into SQL against MaxCompute (ODPS) Information Schema metadata views for metadata analysis. A developer uses it for storage stats, query history, permission audits, cost tracking, governance diagnostics, and zombie-table detection across tables, columns, partitions, tasks_history, and quota_usage views. It runs through the maxcompute-catalog MCP server (preferred) or odpscmd and requires the namespace flag on every tenant-level query.
- Queries MaxCompute (ODPS) Information Schema metadata views for storage, cost, permission, and governance analysis
- Supports tenant-level (SYSTEM_CATALOG.INFORMATION_SCHEMA.*) and deprecated project-level (Information_Schema.*) views
- Runs via the maxcompute-catalog MCP server (preferred) or odpscmd, with a mandatory namespace flag on every tenant-level
Alibabacloud Odps Information Schema by the numbers
- 57 all-time installs (skills.sh)
- +9 installs in the week ending Jun 23, 2026 (Skillselion tracking)
- Ranked #393 of 911 Databases skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
alibabacloud-odps-information-schema capabilities & compatibility
- Works with
- aws
- Use cases
- data analysis · security audit
- Runs
- Runs locally
What alibabacloud-odps-information-schema says it does
Query MaxCompute (ODPS) Information Schema metadata views.
Query MaxCompute metadata through INFORMATION_SCHEMA views for storage, cost, permission, task, and governance analysis.
npx skills add https://github.com/aliyun/alibabacloud-aiops-skills --skill alibabacloud-odps-information-schemaAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 57 |
|---|---|
| repo stars | ★ 208 |
| Last updated | August 4, 2026 |
| Repository | aliyun/alibabacloud-aiops-skills ↗ |
What it does
Query MaxCompute (ODPS) Information Schema views for storage, cost, permission audit, and governance analysis.
Who is it for?
Analysts auditing MaxCompute metadata: storage stats, query history, permission audits, cost tracking, and zombie-table detection.
Skip if: DDL/DML, listing tables via MCP, running ad-hoc SQL, or general MaxCompute questions without IS context.
When should I use this skill?
The user asks about MaxCompute metadata analysis, table storage stats, query history, permission audit, or CU consumption via Information Schema.
By the numbers
- 15 MCP tools with routing guide
- History views have ~5 min delay, realtime views ~3 hours
Files
ODPS Information Schema
This skill is for Information Schema (IS) metadata queries ONLY. If the user's question is about DDL/DML, listing tables, or general MaxCompute usage (not IS views), do NOT use this skill — use MCP tools (list_tables, get_table_schema) or odpscmd instead.
Query MaxCompute metadata through INFORMATION_SCHEMA views for storage, cost, permission, task, and governance analysis.
Prerequisites <a name="prerequisites"></a>
MANDATORY: Every IS query MUST set namespace flag. Without it, ALL queries fail with "Table not found".
- MCP:hints={"odps.namespace.schema":"true"}inexecute_sql
- odpscmd: SET odps.namespace.schema=true; before each query- No exceptions. Applies to ALL SYSTEM_CATALOG.INFORMATION_SCHEMA.* queries.IS views require tenant-level permission. If you get access errors, the user needs tenant-level role — see references/ram-policies.md for Policy template.
Data freshness: History views (TASKS_HISTORY, TUNNELS_HISTORY) have ~5 min delay, realtime views ~3 hours. For yesterday's data, query after 06:00 to ensure completeness.
Tenant-level vs Project-level IS: MaxCompute has two IS levels. Tenant-level (SYSTEM_CATALOG.INFORMATION_SCHEMA.*) is the default — it covers all projects under the same metadata center and is recommended. Project-level (Information_Schema.*) is per-project only, requiresinstall package Information_Schema.systables, and is being deprecated (since 2024-03 new projects no longer auto-install). Key differences: (1) project-level has fewer views (no CATALOGS, VOLUMES, FOREIGN_SERVERS, SCHEMAS, PARTITION_ACCESS_INFO, TABLE_ACCESS_INFO, QUOTA_USAGE; has SCHEMA_PRIVILEGES which tenant lacks); (2) project-level TASKS_HISTORY hastask_schemawhile tenant-level does NOT; (3) project-leveltable_catalogis alwaysodpswhile tenant-level is the actual project name. See Project-level IS Adaptation for transformation rules.
For MCP configuration, see references/mcp-tools-reference.md.
Execution Channels <a name="channels"></a>
MCP preferred when mcp__maxcompute-catalog__* tools are available. Fall back to odpscmd on connection/auth errors.
| Channel | Use For | Key Detail |
|---|---|---|
| MCP (tenant-level) | DQL, metadata, search | execute_sql + hints={"odps.namespace.schema":"true"}; sync limit 1000 rows; cost_sql supports IS views (verified 2026-04) |
| MCP (project-level) | DQL, metadata, search | execute_sql + hints={} (no namespace flag); view prefix: Information_Schema.* |
| odpscmd (tenant-level) | DDL/DML, large results, MCP unavailable | SET odps.namespace.schema=true; prefix required |
| odpscmd (project-level) | DDL/DML, large results, MCP unavailable | No namespace flag; view prefix: Information_Schema.* |
See references/mcp-tools-reference.md for 15 MCP tools with routing guide.
Important Rules <a name="rules"></a>
1. Always set namespace flag — every tenant-level IS query, no exceptions. Project-level IS queries do NOT need this flag 2. Filter by `ds` — TASKS_HISTORY / TUNNELS_HISTORY are partitioned; always add ds filter to avoid full scan 3. No SELECT \ — use explicit column names 4. Cross-metadata-center NOT supported — each region is independent 5. last_access_time is NULL for partitioned tables — use `COALESCE(last_access_time, last_modified_time)` or check PARTITIONS view. Also: not collected for ALGO jobs or Hologres direct reads; up to 24h delay from actual access. 6. status values — TASKS_HISTORY: `Terminated` (normal), `Failed`, `Cancelled` (rare). Never count Terminated as failure. 7. operate_type values — TUNNELS_HISTORY: `UPLOADLOG`, `DOWNLOADLOG`, `DOWNLOADINSTANCELOG`, `STORAGEAPIREAD`, `STORAGEAPIWRITE` 8. Views without time fields — COLUMNS has no time column. TABLE_PRIVILEGES/COLUMN_PRIVILEGES have no time column, only `expired`. These views support static snapshot only, not time-series. 9. cost_cpu / cost_mem are DOUBLE — unit: 100×core×seconds / MB×seconds. Convert to CU-hours: `cost_cpu / 100 / 3600` 10. Duration — use `DATEDIFF(end_time, start_time, 'ss')` (seconds). No `duration_ms` column exists. 11. Non-existent fields trap — see Critical Column Reference below 12. JOIN IS views requires 3-field key* — when joining any two IS views, the ON condition MUST include table_catalog, table_schema, AND table_name. Missing any one causes incorrect results in multi-catalog environments
Project-level IS Adaptation <a name="project-level-adaptation"></a>
All SQL templates in this skill default to tenant-level syntax (SYSTEM_CATALOG.INFORMATION_SCHEMA.* + namespace flag). If the environment only supports project-level IS, apply these mechanical transformations to every generated SQL:
| Transform | Tenant-level (default) | Project-level |
|---|---|---|
| View prefix | SYSTEM_CATALOG.INFORMATION_SCHEMA. | Information_Schema. |
| Namespace flag (MCP) | hints={"odps.namespace.schema":"true"} | hints={} (remove flag) |
| Namespace flag (odpscmd) | SET odps.namespace.schema=true; | Remove entirely |
| Scope | All projects in metadata center | Current project only |
| Views unavailable | — | CATALOGS, VOLUMES, FOREIGN_SERVERS, SCHEMAS, PARTITION_ACCESS_INFO, TABLE_ACCESS_INFO, QUOTA_USAGE |
| View exclusive to this level | — | SCHEMA_PRIVILEGES |
| TASKS_HISTORY extra column | — | task_schema (project name; tenant-level lacks this) |
table_catalog value | Actual project name | Fixed odps |
Example transformation:
-- Tenant-level (default):
SET odps.namespace.schema=true;
SELECT table_name, data_length FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES WHERE ...
-- Project-level (after transformation):
SELECT table_name, data_length FROM Information_Schema.tables WHERE ...When to switch: If a tenant-level query fails with Table not found (and namespace flag is correctly set), or if the user explicitly says they only have project-level IS, apply the transformation rules above to all subsequent queries.
Critical Column Name Reference <a name="column-reference"></a>
| Concept | Correct | Wrong |
|---|---|---|
| Table size | data_length | ~~size_bytes~~, ~~size~~ |
| Task instance | inst_id | ~~task_id~~ |
| Task submitter | owner_name | ~~task_owner~~ |
| Task project | task_catalog (tenant-level) | ~~project_name~~, ~~task_schema~~ (project-level IS only) |
| Task error | result | ~~error_message~~ |
| Task duration | DATEDIFF(end_time, start_time, 'ss') | ~~duration_ms~~ |
| Task status | status | ~~task_status~~ |
| Task input size | input_bytes | ~~scan_bytes~~, ~~processed_bytes~~ |
| Table comment | table_comment | ~~comment~~ |
| Column comment | column_comment | ~~comment~~ |
| Privilege grantee | user_name, user_id | ~~grantee~~ |
| Privilege time | expired | ~~grant_time~~ |
| Resource size | size | ~~size_bytes~~ |
| Tunnel session | session_id | ~~tunnel_id~~ |
| Tunnel data size | data_size | ~~size_bytes~~ |
| User identity | identity_provider | — |
| Timestamp type | DATETIME | ~~TIMESTAMP~~ |
| Table modified | last_modified_time | ~~last_ddl_time~~ |
| cost_cpu type | DOUBLE | ~~BIGINT~~ |
For verified query examples using these columns, see references/verified-queries.md.
Routing Index <a name="routing"></a>
SKILL.md contains critical column names and namespace rules. Load sub-files only when needed:
- If multiple rows match, load ALL matched files. E.g., a non-English term causal query needs both terminology.md and playbooks+causal-templates.
- If SKILL.md inline info (tables below) is sufficient, do NOT load extra files.
- NOT about IS views? → This skill is not applicable. Use MCP tools (list_tables, get_table_schema, execute_sql) or odpscmd for DDL/DML/general queries.
| Query Type | When | Load Extra File |
|---|---|---|
| NOT an IS query | DDL/DML, list tables, run SQL, general ODPS | None — use MCP tools or odpscmd instead |
| Single-view query | One IS view, no JOIN | None — SKILL.md only |
| Live monitoring | TASKS / QUOTA_USAGE | None — SKILL.md only |
| 2+ IS view JOIN | Combining views | references/joins.md |
| Named metric/template | "comment coverage", "CU trend", "zombie table detection" | references/verified-queries.md + references/metrics.md |
| Multi-step diagnosis | "Why did CU spike?", root-cause analysis | references/playbooks.md + references/causal-templates.md |
| Non-English synonyms | "cpu时间", "作业时长", "存储占用", or any CJK/localized terms | references/terminology.md (or use inline mapping below) |
| Schema/field lookup | "What columns does X have?" | references/views-reference.md |
| Access denied error | Permission denied on IS view | references/ram-policies.md |
| Troubleshooting | Table not found, timeout, etc. | references/TROUBLESHOOTING.md |
Anti-pattern: Do NOT load extra files for these
| User says | Looks like | Actually is | Load |
|---|---|---|---|
| "storage pressure, list top 20 tables" | Diagnostics | Single-view | SKILL.md only |
| "permission audit, who has SELECT on X" | Playbook | Single-view | SKILL.md only |
| "cost attribution by owner" | Causal | Single-view | SKILL.md only |
<!-- SYNC: derived from references/joins.md paths #1 #2 #3 #4 #5 #8 #10 -->
Inline Join Conditions (for 2+ view JOINs)
When joining IS views, you MUST include table_catalog, table_schema, AND table_name in join conditions. Common join paths:
| Left | Right | Join Condition |
|---|---|---|
| TABLES | COLUMNS | t.table_catalog = c.table_catalog AND t.table_schema = c.table_schema AND t.table_name = c.table_name |
| TABLES | PARTITIONS | t.table_catalog = p.table_catalog AND t.table_schema = p.table_schema AND t.table_name = p.table_name |
| TABLES | TABLE_PRIVILEGES | t.table_catalog = p.table_catalog AND t.table_schema = p.table_schema AND t.table_name = p.table_name |
| TABLES | TABLE_ACCESS_INFO | t.table_catalog = a.table_catalog AND t.table_schema = a.table_schema AND t.table_name = a.table_name |
| TABLES | TABLE_LABELS | t.table_catalog = l.table_catalog AND t.table_schema = l.table_schema AND t.table_name = l.table_name |
| USERS | USER_ROLES | u.user_id = ur.user_id |
| COLUMNS | COLUMN_LABELS | c.table_catalog = l.table_catalog AND c.table_schema = l.table_schema AND c.table_name = l.table_name AND c.column_name = l.column_name |
For all 16 join paths, see references/joins.md. The 7 most common paths are inlined below.
<!-- SYNC: derived from references/terminology.md — metric terms: storage usage, task CPU consumption, task execution duration, CU-hours, queue wait; dimension terms: zombie tables; metric: task failure rate -->
Inline Terminology Mapping (common non-English terms)
| Non-English term | English equivalent | Correct column/source | Common mistake |
|---|---|---|---|
| cpu时间 / CPU消耗 | CPU time / CPU consumption | cost_cpu (DOUBLE), ÷100÷3600 = CU·hour | ~~cpu_time~~ |
| 作业时长 / 任务耗时 | Task duration / task elapsed time | DATEDIFF(end_time, start_time, 'ss') | ~~duration_ms~~ |
| 存储占用 / 表大小 | Storage usage / table size | data_length (÷1073741824 = GB) | ~~size_bytes~~ |
| 僵尸表 | Zombie table | TABLES + TABLE_ACCESS_INFO | — |
| 排队时间 | Queue wait time | NOT available in IS views | — |
| CU时 / CU消耗 | CU-hours / CU consumption | SUM(cost_cpu) / 100.0 / 3600 | — |
| 任务失败率 | Task failure rate | status='Failed' ratio in TASKS_HISTORY | — |
For all 59 terms, see references/terminology.md.
Error Recovery <a name="error-recovery"></a>
| Error Signal | Root Cause | Fix |
|---|---|---|
Table not found on IS view | Missing namespace flag | Add SET odps.namespace.schema=true; / hints={"odps.namespace.schema":"true"}. Verify with Q30 smoke test |
Access denied / Permission denied on IS view | Missing tenant-level role | Verify access with check_access(include_grants=true). User needs tenant-level role — load references/ram-policies.md for Policy template |
Table not found on SYSTEM_CATALOG.INFORMATION_SCHEMA.* (namespace flag correctly set) | Environment only supports project-level IS | Apply Project-level IS Adaptation transformation rules to all subsequent queries: switch prefix to Information_Schema.*, remove namespace flag |
Information_Schema not found / Package not installed | Project-level IS not installed in this project | User must run install package Information_Schema.systables as project owner or Super_Administrator. After install, query as Information_Schema.view_name (no namespace flag). Note: project-level IS is being deprecated — prefer tenant-level |
Object 'Information_Schema' not found on new project | New projects (since 2024-03) don't auto-install project-level IS | Switch to tenant-level IS (SYSTEM_CATALOG.INFORMATION_SCHEMA.*) or manually install package |
| TASKS_HISTORY query slow/expensive | No ds filter | Add WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd') |
| MCP returns exactly 1000 rows | Sync limit truncation | Re-run with async=true, or add tighter WHERE/LIMIT |
Column not found | Used non-existent column | Check Critical Column Reference above — common: size_bytes→data_length, task_status→status |
| TUNNELS_HISTORY sync timeout (>30s) | Tunnel record volume much larger than TASKS_HISTORY | Use async=true + get_instance, or reduce ds to 1 day |
| Async timeout (>30s) | Large scan | Use cost_sql first; add ds filter; split query |
| IS view shows no recent data | ~5 min delay for history views | Query yesterday's data after 06:00 |
| odpscmd query hangs | Large result set or full-table scan | Use odps_is_query.sh -t <seconds> to set timeout (default 300s); add ds filter |
Namespace flag set but still Table not found | Other causes (wrong project, typo, schema issue) | Load references/TROUBLESHOOTING.md for T1–T7 scenarios |
Core Views <a name="core-views"></a>
| View | Purpose | Key Columns |
|---|---|---|
TABLES | Table metadata | table_name, owner_name, data_length, table_type, lifecycle, last_modified_time |
COLUMNS | Column metadata | column_name, data_type, column_comment, is_partition_key |
PARTITIONS | Partition metadata | partition_name, data_length, create_time, last_modified_time |
TASKS | Running jobs (live, seconds delay) | inst_id, task_name, owner_name, status, cpu_usage (core×100), mem_usage (MB) |
TASKS_HISTORY | Query history | inst_id, task_name, owner_name, status, task_type, start_time, end_time, result, cost_cpu, input_bytes, ds |
TUNNELS_HISTORY | Tunnel history | session_id, object_name, operate_type, data_size, owner_name, ds |
TABLE_PRIVILEGES | Table permissions | table_name, user_name, privilege_type, expired |
TABLE_ACCESS_INFO ⚠️ | Table access stats | table_name, access_count, access_bytes, last_access_time |
QUOTA_USAGE | Subscription quota monitoring | name, cpu_elastic_quota_max, cpu_elastic_quota_used, mem_elastic_quota_max, mem_elastic_quota_used |
USERS | Project users | user_name, user_id, identity_provider |
USER_ROLES | User-role mapping | user_name, role_name, user_role_catalog |
CATALOGS ⚠️ | Project list | catalog_name, status, owner_name, region |
For all 31 views with complete field definitions, see references/views-reference.md. Views marked ⚠️ are tenant-level only (not available in project-level IS).
Additional Resources <a name="resources"></a>
- references/views-reference.md — Complete field definitions for all 31 IS views
- references/verified-queries.md — 30 pre-validated SQL query templates (including smoke test)
- references/entities.md — Entity-to-table mapping
- references/metrics.md — Metric definitions with SQL expressions
- references/joins.md — Join paths between views
- references/playbooks.md — 23 diagnostic scenario playbooks
- references/causal-templates.md — Root-cause analysis templates
- references/terminology.md — 59-term synonym dictionary for NL2SQL
- references/ram-policies.md — Tenant permission setup and Policy template
- references/mcp-tools-reference.md — 15 MCP tools with routing guide + MCP setup + installation
- scripts/odps_is_query.sh — CLI query tool (16 query types + custom, including smoke-test). Supports
-t <seconds>for timeout (default 300s),-d YYYYMMDDfor date,-pfor project. Custom mode only allows SELECT (DDL/DML rejected). - references/TROUBLESHOOTING.md — 7 error scenarios with fix templates (T1–T7)
Official Documentation <a name="docs"></a>
Causal Analysis Templates
Related: playbooks.md, verified-queries.md, SKILL.md
Root-cause investigation patterns. Each template defines: trigger condition, hypothesis dimensions with weights, verification queries, and recommendations.
MCP Tip: Before running causal analysis queries, use check_access to verify permissions and get_project to check project configuration. Use list_tables to confirm the existence of relevant IS views.
Placeholder Filling Rules
These rules apply to all templates below:
- Date placeholders: Always use
DATEADDexpressions, not literal date strings (format may be wrong, and TASKS_HISTORY has ~5 min delay): <yesterday>→TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')<today>→ Avoid using (data may be incomplete due to delay); if required, useTO_CHAR(GETDATE(), 'yyyymmdd')<baseline_period>→TO_CHAR(DATEADD(GETDATE(), -8, 'dd'), 'yyyymmdd')throughTO_CHAR(DATEADD(GETDATE(), -2, 'dd'), 'yyyymmdd')- `{{primary_dimension}}`: Select the dimension with the highest
(weight × percentage_change). Example: ifowner_name(weight 0.45) changed 40% andtask_type(weight 0.30) changed 20%, pickowner_namebecause 0.45 × 40 = 18 > 0.30 × 20 = 6. - `ds` filter: Every TASKS_HISTORY/TUNNELS_HISTORY query MUST include a
dsfilter.
1. Cost Spike Analysis (cost_spike)
Trigger: CU-hour consumption increased by 20%+ compared to baseline.
Hypothesis Dimensions:
owner_name(weight: 0.45) -- Which user submitted the most additional tasks?task_type(weight: 0.30) -- Is a specific task type driving the increase?task_catalog(weight: 0.25) -- Is the increase concentrated in one project?
Verification Queries:
-- By owner_name
SELECT owner_name, COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds IN (TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd'), TO_CHAR(GETDATE(), 'yyyymmdd'))
GROUP BY owner_name
ORDER BY cu_hours DESC
LIMIT 10;
-- By task_type
SELECT task_type, COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds IN (TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd'), TO_CHAR(GETDATE(), 'yyyymmdd'))
GROUP BY task_type
ORDER BY cu_hours DESC;
-- By task_catalog
SELECT task_catalog, COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds IN (TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd'), TO_CHAR(GETDATE(), 'yyyymmdd'))
GROUP BY task_catalog
ORDER BY cu_hours DESC
LIMIT 10;Judgment Rules:
- Support hypothesis: If cost proportion change for a specific dimension value exceeds 20%
- Refute hypothesis: If all dimension values show stable cost distribution (change < 5%)
Recommended Actions:
- Check {{primary_dimension}} task queue for abnormal tasks
- Consider setting cost alert thresholds for {{primary_dimension}}
2. Storage Spike Analysis (storage_spike)
Trigger: Total storage increased by 30%+ compared to baseline.
Hypothesis Dimensions:
table_name(weight: 0.50) -- Which table grew the most?owner_name(weight: 0.35) -- Which owner's tables grew?table_catalog(weight: 0.15) -- Is the growth in one project?
Verification Queries:
-- Top growing tables
SELECT table_name, owner_name, COALESCE(data_length, 0) / 1024 / 1024 / 1024 AS size_gb,
lifecycle
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
WHERE table_type = 'MANAGED_TABLE'
ORDER BY COALESCE(data_length, 0) DESC
LIMIT 20;
-- Storage by owner
SELECT owner_name,
COUNT(*) AS table_count,
SUM(COALESCE(data_length, 0)) / 1024 / 1024 / 1024 AS total_tb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
GROUP BY owner_name
ORDER BY total_tb DESC;Judgment Rules:
- Support hypothesis: If storage proportion change for a specific dimension value exceeds 30%
- Refute hypothesis: If all dimension values show stable storage distribution
Recommended Actions:
- Check {{primary_dimension}} data import task frequency
- Consider setting lifecycle policies to clean up expired data
3. Job Failure Spike Analysis (job_failure_spike)
Trigger: Task failure rate increased by 15%+ compared to baseline.
Hypothesis Dimensions:
task_catalog(weight: 0.40) -- Is failure concentrated in one project?task_type(weight: 0.35) -- Is a specific task type failing?owner_name(weight: 0.25) -- Is one user's jobs failing?
Verification Queries:
-- Failure rate by project
SELECT task_catalog,
COUNT(*) AS total,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) AS failed,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS failure_rate
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY task_catalog
ORDER BY failed DESC;
-- Failure details
SELECT task_name, task_type, owner_name, start_time, result
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
AND status = 'Failed'
ORDER BY start_time DESC;Recommended Actions:
- Check {{primary_dimension}} resource configuration for adequacy
- Consider increasing {{primary_dimension}} compute resource quota
4. Partition Growth Analysis (partition_growth)
Trigger: Partition count increased by 50%+ on a table.
Hypothesis Dimensions:
table_name-- Which tables have the most partitions?partition_pattern-- Are partitions following expected naming patterns?
Verification Queries:
-- Tables with most partitions
SELECT table_name,
COUNT(*) AS partition_count,
SUM(data_length) / 1024 / 1024 AS size_mb,
MIN(partition_name) AS oldest_partition,
MAX(partition_name) AS newest_partition
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS
GROUP BY table_name
HAVING COUNT(*) > 5000
ORDER BY partition_count DESC;Recommendation Template:
- Set lifecycle on partitioned tables to auto-expire old partitions
- Consider partition-level merges for small partitions
- Review partition creation scripts for unintended patterns
5. Permission Change Analysis (permission_change)
Trigger: Grant count changed by 25%+ compared to baseline.
Hypothesis Dimensions:
user_name-- Who received new permissions?privilege_type-- What type of permissions changed?table_name-- Which tables had permission changes?
Verification Queries:
-- Permission distribution (active grants only)
SELECT user_name, privilege_type, COUNT(*) AS grant_count
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES
WHERE expired IS NULL OR expired > GETDATE()
GROUP BY user_name, privilege_type
ORDER BY grant_count DESC;
-- Tables with most grantees (active grants only)
SELECT table_name, COUNT(DISTINCT user_name) AS grantee_count
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES
WHERE expired IS NULL OR expired > GETDATE()
GROUP BY table_name
ORDER BY grantee_count DESC
LIMIT 20;Recommendation Template:
- Review recent grant activities for unexpected changes
- Ensure least-privilege principle is maintained
- Check for orphan users (users with permissions but no active roles)
Entities Reference
Related: views-reference.md, terminology.md, SKILL.md
Entity-to-table mappings for INFORMATION_SCHEMA views. All queries use SYSTEM_CATALOG.INFORMATION_SCHEMA.*.
Entity-Table Mapping
| Entity ID | Entity Name | Source Table | Primary Key | Time Field | Purpose | MCP Tool |
|---|---|---|---|---|---|---|
| entity_table_asset | Table Asset | TABLES | table_name | last_modified_time | Table-level metadata, storage, lifecycle | list_tables + get_table_schema |
| entity_column | Column | COLUMNS | column_name | — | Column definitions, types, comments | get_table_schema |
| entity_partition | Table Partition | PARTITIONS | partition_name | create_time | Partition details, sizes, counts | get_partition_info |
| entity_privilege | Privilege Grant | TABLE_PRIVILEGES | user_id | — | Table-level grants | execute_sql + hints |
| entity_column_privilege | Column Privilege | COLUMN_PRIVILEGES | — | — | Column-level grants | execute_sql + hints |
| entity_task | Compute Task | TASKS_HISTORY | inst_id | start_time | Historical query analysis | execute_sql + hints |
| entity_running_task | Running Task | TASKS | inst_id | start_time | Live running job monitoring | execute_sql + hints |
| entity_catalog | Project (Catalog) | CATALOGS | catalog_name | create_time | Project-level info and properties | get_project |
| entity_catalog_privilege | Project Privilege | CATALOG_PRIVILEGES | — | — | Project-level permissions | execute_sql + hints |
| entity_schema | Schema | SCHEMAS | schema_name | — | Schema metadata | list_schemas |
| entity_user | User | USERS | user_id | — | Project users | execute_sql + hints |
| entity_role | Role | ROLES | role_name | — | Project roles | execute_sql + hints |
| entity_user_role | User Role | USER_ROLES | — | — | User-role assignments | execute_sql + hints |
| entity_udf | UDF | UDFS | udf_name | — | User-defined functions | execute_sql + hints |
| entity_udf_privilege | UDF Privilege | UDF_PRIVILEGES | — | — | UDF permissions | execute_sql + hints |
| entity_udf_resource | UDF Resource | UDF_RESOURCES | — | — | Resources used by UDFs | execute_sql + hints |
| entity_resource | Resource | RESOURCES | resource_name | — | Uploaded resources | execute_sql + hints |
| entity_resource_privilege | Resource Privilege | RESOURCE_PRIVILEGES | — | — | Resource permissions | execute_sql + hints |
| entity_tunnel_history | Tunnel History | TUNNELS_HISTORY | session_id | ds | Data transfer audit trail | execute_sql + hints |
| entity_quota_usage | Quota Usage | QUOTA_USAGE | name | last_modified_time | Resource quota monitoring | execute_sql + hints |
| entity_volume | Volume Storage | VOLUMES | volume_name | — | Volume filesystem metadata | execute_sql + hints |
| entity_foreign_server | Foreign Server | FOREIGN_SERVERS | server_name | — | External data source definitions | execute_sql + hints |
| entity_installed_package | Installed Package | INSTALLED_PACKAGES | package_name | — | Installed packages | execute_sql + hints |
| entity_package_privilege | Package Privilege | PACKAGE_PRIVILEGES | — | — | Package permissions | execute_sql + hints |
| entity_package_object | Package Object | PACKAGE_OBJECTS | — | — | Objects within packages | execute_sql + hints |
| entity_table_access_info | Table Access Info | TABLE_ACCESS_INFO | — | ds | Table access patterns and statistics | execute_sql + hints |
| entity_table_label | Table Security Label | TABLE_LABELS | — | — | Table-level LABEL security | execute_sql + hints |
| entity_table_label_grant | Table Label Grant | TABLE_LABEL_GRANTS | — | — | Table label grants | execute_sql + hints |
| entity_column_label | Column Security Label | COLUMN_LABELS | — | — | Column-level LABEL security | execute_sql + hints |
| entity_column_label_grant | Column Label Grant | COLUMN_LABEL_GRANTS | — | — | Column label grants | execute_sql + hints |
| entity_partition_access_info | Partition Access Info | PARTITION_ACCESS_INFO | — | ds | Partition access patterns | execute_sql + hints |
Join Paths Reference
Related: views-reference.md, verified-queries.md, SKILL.md
Trusted join relationships between INFORMATION_SCHEMA views. All views are in SYSTEM_CATALOG.INFORMATION_SCHEMA.
Important: Always include table_catalog in join conditions for robustness, especially for non-3-tier model projects where table_schema may be NULL.
MCP Tip: Before constructing multi-table JOINs, use list_tables to confirm tables exist and get_table_schema to verify column names. This prevents errors from misspelled table/column names in complex queries.
Join Paths
| # | Left Table | Right Table | Join Condition | Purpose |
|---|---|---|---|---|
| 1 | TABLES | COLUMNS | t.table_catalog = c.table_catalog AND t.table_schema = c.table_schema AND t.table_name = c.table_name | Table + column metadata |
| 2 | TABLES | PARTITIONS | t.table_catalog = p.table_catalog AND t.table_schema = p.table_schema AND t.table_name = p.table_name | Table + partition details |
| 3 | TABLES | TABLE_PRIVILEGES | t.table_catalog = p.table_catalog AND t.table_schema = p.table_schema AND t.table_name = p.table_name | Table + permissions |
| 4 | TABLES | TABLE_ACCESS_INFO | t.table_catalog = a.table_catalog AND t.table_schema = a.table_schema AND t.table_name = a.table_name | Table + access statistics |
| 5 | TABLES | TABLE_LABELS | t.table_catalog = l.table_catalog AND t.table_schema = l.table_schema AND t.table_name = l.table_name | Table + security labels |
| 6 | PARTITIONS | PARTITION_ACCESS_INFO | p.table_catalog = a.table_catalog AND p.table_schema = a.table_schema AND p.table_name = a.table_name AND p.partition_name = a.partition_name | Partition + access statistics |
| 7 | CATALOGS | SCHEMAS | c.catalog_name = s.schema_catalog | Project + schema hierarchy |
| 8 | USERS | USER_ROLES | u.user_id = ur.user_id | User + role assignments |
| 9 | USER_ROLES | ROLES | ur.role_name = r.role_name AND ur.user_role_catalog = r.role_catalog | Role assignments + role details |
| 10 | COLUMNS | COLUMN_LABELS | c.table_catalog = l.table_catalog AND c.table_schema = l.table_schema AND c.table_name = l.table_name AND c.column_name = l.column_name | Column + security labels |
| 11 | COLUMNS | COLUMN_PRIVILEGES | c.table_catalog = p.table_catalog AND c.table_schema = p.table_schema AND c.table_name = p.table_name AND c.column_name = p.column_name | Column + permissions |
| 12 | UDFS | UDF_RESOURCES | u.udf_catalog = r.udf_catalog AND u.udf_schema = r.udf_schema AND u.udf_name = r.udf_name | UDF + resource dependencies |
| 13 | UDFS | UDF_PRIVILEGES | u.udf_catalog = p.udf_catalog AND u.udf_schema = p.udf_schema AND u.udf_name = p.udf_name | UDF + permissions |
| 14 | INSTALLED_PACKAGES | PACKAGE_OBJECTS | p.package_catalog = o.package_catalog AND p.package_name = o.package_name | Package + contained objects |
| 15 | INSTALLED_PACKAGES | PACKAGE_PRIVILEGES | p.package_catalog = pp.package_catalog AND p.package_name = pp.package_name | Package + permissions |
| 16 | RESOURCES | RESOURCE_PRIVILEGES | r.resource_catalog = p.resource_catalog AND r.resource_schema = p.resource_schema AND r.resource_name = p.resource_name | Resource + permissions |
Common Multi-Table Queries
Table + Column + Privilege
SELECT t.table_catalog, t.table_name, t.owner_name, t.data_length,
c.column_name, c.data_type, c.column_comment,
p.user_name, p.privilege_type
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.COLUMNS c
ON t.table_catalog = c.table_catalog AND t.table_name = c.table_name
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES p
ON t.table_catalog = p.table_catalog AND t.table_name = p.table_name
WHERE t.table_name = 'my_table';Table + Partition Count
SELECT t.table_catalog, t.table_name, t.owner_name, t.data_length,
COUNT(DISTINCT p.partition_name) AS partition_count
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS p
ON t.table_catalog = p.table_catalog AND t.table_name = p.table_name
WHERE t.table_type = 'MANAGED_TABLE'
GROUP BY t.table_catalog, t.table_name, t.owner_name, t.data_length
ORDER BY t.data_length DESC
LIMIT 20;User + Role + Permission Chain
SELECT ur.user_role_catalog, ur.user_name, ur.user_id,
r.role_name, r.role_label
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.USER_ROLES ur
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.ROLES r
ON ur.role_name = r.role_name AND ur.user_role_catalog = r.role_catalog
ORDER BY ur.user_role_catalog, ur.user_name;Admin Role Users
SELECT user_role_catalog, role_name, user_name, user_id
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.USER_ROLES
WHERE role_name IN ('super_administrator', 'admin')
ORDER BY user_role_catalog, role_name;Data Lineage: Upstream Tables
SELECT task_catalog, task_name, inst_id, input_tables, output_tables
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
AND input_tables LIKE '%my_project.my_table%'
ORDER BY end_time DESC
LIMIT 50;Data Lineage: Downstream Tables
SELECT task_catalog, task_name, inst_id, output_tables
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
AND output_tables LIKE '%my_project.my_table%'
ORDER BY end_time DESC
LIMIT 50;Project Settings Audit
SELECT catalog_name, region, status,
get_json_object(json_parse(settings), '$."odps.timemachine.retention.days"') AS backup_days,
get_json_object(json_parse(settings), '$."odps.security.ip.whitelist"') AS ip_whitelist,
get_json_object(json_parse(settings), '$."odps.sql.metering.value.max"') AS sql_cost_limit
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.CATALOGS;Storage Tier Distribution
SELECT storage_tier,
COUNT(*) AS table_count,
SUM(COALESCE(data_length, 0)) / 1024 / 1024 / 1024 AS storage_gb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
WHERE table_type = 'MANAGED_TABLE'
GROUP BY storage_tier
ORDER BY storage_gb DESC;Permission Exposure Analysis
SELECT table_catalog, table_schema, table_name,
COUNT(DISTINCT user_name) AS user_count,
COLLECT_SET(privilege_type) AS privilege_types
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES
GROUP BY table_catalog, table_schema, table_name
ORDER BY user_count DESC
LIMIT 50;MCP Tools Reference
Related: SKILL.md
Complete reference for maxcompute-catalog MCP tools used by odps_is skill. This document supplements SKILL.md with detailed MCP execution guidance.
MCP Availability Detection
If mcp__maxcompute-catalog__* tools are available in your tool list, use MCP as the primary channel. If an MCP tool call returns a connection error or auth failure, fall back to odpscmd for all subsequent queries.
Degradation rules: 1. Connection/auth error → mark MCP unavailable, use odpscmd for all subsequent queries 2. SQL execution error (syntax, permission) → do NOT degrade, this is a business-level error 3. Result truncation (exactly 1000 rows) → warn user, suggest odpscmd for complete data
Tool Overview
| Tool Name | Category | Purpose | IS Query Applicable |
|---|---|---|---|
| list_projects | Metadata Exploration | List accessible projects | No (use CATALOGS SQL) |
| get_project | Metadata Exploration | Project details, schemaEnabled detection | No (use CATALOGS SQL) |
| list_schemas | Metadata Exploration | List schemas under project | No (use SCHEMAS SQL) |
| get_schema | Metadata Exploration | Schema details | No |
| list_tables | Metadata Exploration | List tables/views, namingModel | Yes (for table listing) |
| get_table_schema | Metadata Exploration | Column details, sqlTableRef | Yes (for column info) |
| get_partition_info | Metadata Exploration | Partition list with sizes | Yes (for partition info) |
| execute_sql | SQL Execution | Run DQL queries | Yes (primary IS query path) |
| cost_sql | SQL Execution | Estimate query cost | Yes (supports IS views, verified 2026-04) |
| get_instance_status | SQL Execution | Poll async job status | Yes (for async queries) |
| get_instance | SQL Execution | Get async query results | Yes (for async queries) |
| search_meta_data | Search | Cross-project table search | No (for table discovery) |
| check_access | Security | Verify identity and permissions | No (for auth check) |
| create_table | Table Design | Create tables via SDK API | No |
| insert_values | Table Design | Insert data rows | No |
Metadata Exploration
list_projects / get_project
list_projects: Lists all accessible project IDs (paginated viapageSize+token)get_project: Returns project details includingschemaEnabled(critical for determining 2-level vs 3-level naming model)- Fallback:
SELECT * FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.CATALOGS
list_schemas / get_schema
list_schemas: Lists schemas under a project (returns synthetic "default" for 2-level projects)get_schema: Returns schema details and metadata- Fallback:
SELECT * FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.SCHEMAS
list_tables
- Lists tables/views in a project
- Returns
namingModel("3-level" or "2-level") to guide SQL table references - Supports
filterparameter for table name prefix matching - Fallback: odpscmd SQL
get_table_schema
- Returns column names, types, partition keys
- Critical: Returns
sqlTableRef(exact table reference for SQL) andsqlExample - Always call this before writing SQL to ensure correct table reference format
- Fallback: odpscmd SQL
get_partition_info
- Lists partitions with data size, create_time, last_modified_time
- Paginated (
pageSize+token) - Fallback: odpscmd SQL
SQL Execution
execute_sql
Execute SQL queries. Key parameters:
| Parameter | Description | Default |
|---|---|---|
sql | The SQL statement | (required) |
project | Billing project (for IS queries, use defaultProject from config) | defaultProject |
hints | Runtime parameters merged with default {"odps.sql.submit.mode":"script"} | {} |
async | Async execution mode | true |
maxCU | Resource limit (cost check before execution) | - |
timeout | Sync mode timeout in seconds | 30 |
Namespace Flag (verified): Two working methods (choose one): 1. Via hints: hints={"odps.namespace.schema":"true"} (recommended) 2. Via SQL prefix: SET odps.namespace.schema=true; SELECT ... (also works, MCP uses script mode)
DQL Whitelist: SELECT, WITH, SHOW, DESC, DESCRIBE, EXPLAIN, VALUES, SET
DML Blacklist: INSERT, UPDATE, DELETE, MERGE, UPSERT, TRUNCATE, CREATE, DROP, ALTER, RENAME, GRANT, REVOKE, CALL, EXEC, EXECUTE, LOAD, UNLOAD, COPY, MSCK, REPAIR
Result Format:
- Sync mode (open_reader path):
{"success":true, "columns":[...], "data":[...], "rowCount":N}— max 1000 rows - Sync mode (no open_reader):
{"success":true, "data":["line1","line2"], "rawOutput":"...", "rowCount":N}— for SHOW/DESC - 1000-row truncation: if rowCount === 1000, warn user that results may be incomplete
cost_sql
- Estimates CU cost, input bytes, complexity without executing
- Supports both user tables and IS views (verified 2026-04): Returns real estimates including
estimatedCU,inputBytes,complexity,udfCount - Recommended before executing multi-day TASKS_HISTORY or TUNNELS_HISTORY queries to avoid unexpected costs
get_instance_status
- Poll async job: status, CU usage, progress, logView URL
- Returns:
instanceId,status(RUNNING/TERMINATED/FAILED),isTerminated,isSuccessful
get_instance
- Retrieve completed async query results
- No row limit (unlike sync execute_sql)
- Result format varies:
- Has open_reader → structured JSON:
{"columns":[...], "data":[...]} - No open_reader → CSV string:
"col1","col2"\n"val1","val2" - Agent should handle both formats
Async Execution Pattern
When to use async=true (meet ANY condition): 1. Query involves TASKS_HISTORY/TUNNELS_HISTORY with ds range >= 7 days 2. Expected result rows > 500 3. Multi-table JOIN involving large tables (TABLES/PARTITIONS full scan) 4. Sync mode timeout (instanceId returned after timeout)
Pattern: 1. Submit: execute_sql(async=true, hints={"odps.namespace.schema":"true"}) → get instanceId 2. Poll: get_instance_status(instanceId) → check isTerminated 3. Retrieve: get_instance(instanceId) → get results
Search
search_meta_data
- Cross-project search for tables/resources/schemas
- Requires namespace_id configuration (config.json or
MAXCOMPUTE_NAMESPACE_IDenv var) - Query syntax:
name:foo,type=TABLEordescription:bar,type=TABLE,project=proj - Type is mandatory: TABLE, RESOURCE, or SCHEMA
- Fallback when unavailable: SQL LIKE query on IS views
Security
check_access
- Returns identity info (account type, masked AK, default project)
- Optional:
include_grants=trueto run SHOW GRANTS - Use to verify MCP connection and permissions before complex operations
Table Design
create_table
- Creates tables using pyodps SDK
compute.create_table()(NOT execute_sql) - Supports
columns,partitionColumns,lifecycle,comment - Fallback: odpscmd DDL
insert_values
- Inserts rows via
compute.run_sql()with SQL injection protection - Backtick-escaped identifiers, quoted values
- Supports partitioned tables (groups by partition key)
- Fallback: odpscmd DML
IS Query Patterns via MCP
Pattern 1: Simple IS Query (sync)
execute_sql(
sql="SELECT table_name, data_length FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES LIMIT 20",
hints={"odps.namespace.schema":"true"},
async=false
)Pattern 2: Historical IS Query (async)
execute_sql(
sql="SELECT ds, COUNT(*) AS task_count FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd') GROUP BY ds ORDER BY ds DESC",
hints={"odps.namespace.schema":"true"},
async=true
)
→ get_instance_status(instanceId) until isTerminated
→ get_instance(instanceId)Pattern 3: Metadata First, Then SQL
1. list_tables(filter="my_table") → confirm table exists
2. get_table_schema(table="my_table") → get sqlTableRef
3. execute_sql(sql="SELECT ... FROM <sqlTableRef> ...", hints={"odps.namespace.schema":"true"})Routing Decision Matrix
| Intent Category | NL Trigger Examples | MCP Tool | SQL Method | Fallback |
|---|---|---|---|---|
| List projects | "有哪些项目"、"project列表" | list_projects | - | IS SQL: SELECT * FROM CATALOGS |
| Project details | "项目配置"、"schemaEnabled" | get_project | - | IS SQL: SELECT * FROM CATALOGS WHERE ... |
| List schemas | "有哪些schema"、"数据库列表" | list_schemas | - | IS SQL: SELECT * FROM SCHEMAS |
| List tables | "有哪些表"、"表列表"、"xxx开头的表" | list_tables | - | odpscmd SQL |
| Table schema | "表结构"、"有哪些列"、"字段类型" | get_table_schema | - | odpscmd SQL |
| Partition info | "分区列表"、"有多少分区" | get_partition_info | - | odpscmd SQL |
| Search tables | "搜索表"、"找表"、"哪个项目有xxx表" | search_meta_data | - | IS SQL: LIKE query |
| Permission check | "我有什么权限"、"SHOW GRANTS" | check_access | - | odpscmd: SHOW GRANTS |
| Create table | "建表"、"创建表" | create_table | - | odpscmd DDL |
| Insert data | "插入数据"、"INSERT" | insert_values | - | odpscmd DML |
| IS metadata query | "存储最大的表"、"注释覆盖率"、"权限分布" | - | MCP execute_sql | odpscmd |
| Large result set (>500 rows) | "列出所有权限"、"全量用户列表" | - | MCP async or odpscmd | odpscmd |
| Complex computation | "P99时长"、"多表JOIN分析" | - | MCP execute_sql | odpscmd |
| DDL/DML | "ALTER TABLE"、"DROP"、"UPDATE" | - | odpscmd | - |
| SHOW/DESC | "SHOW TABLES"、"DESC table" | - | MCP execute_sql | odpscmd |
| Cost estimation (user tables & IS views) | "查询费用预估"、"这个SQL多少钱" | cost_sql | - | - |
MCP Setup
1. Install maxcompute-catalog-mcp Python package 2. Create config file (e.g., config.json):
{
"maxcompute": {
"catalogapi_endpoint": "catalogapi.cn-hangzhou.maxcompute.aliyun.com",
"maxcompute_endpoint": "http://service.odps.aliyun.com/api",
"accessKeyId": "YOUR_AK",
"accessKeySecret": "YOUR_SK",
"defaultProject": "YOUR_PROJECT",
"namespaceId": "YOUR_NAMESPACE_ID"
}
}Security warning: Never commit real credentials to source control. Use environment variables or a secrets manager. Addconfig.jsonto.gitignore.
Important: catalogapi_endpoint must NOT include https:// prefix.
3. Add to .mcp.json in your project root:
{
"mcpServers": {
"maxcompute-catalog": {
"command": "/path/to/python3",
"args": ["-m", "maxcompute_catalog_mcp", "--config", "/path/to/config.json"]
}
}
}Configuration Keys
| Key | Required | Description |
|---|---|---|
catalogapi_endpoint | Yes | Catalog API endpoint (domain only, no https://) |
maxcompute_endpoint | Yes | MaxCompute service endpoint |
accessKeyId | Yes | Alibaba Cloud AccessKey ID |
accessKeySecret | Yes | Alibaba Cloud AccessKey Secret |
defaultProject | Yes | Default project for SQL execution and billing |
namespaceId | For search | Namespace ID for search_meta_data (also supports env var MAXCOMPUTE_NAMESPACE_ID) |
Verification
After configuration, verify MCP works: 1. check_access → Should return identity info 2. list_tables → Should return table list with namingModel 3. execute_sql with hints={"odps.namespace.schema":"true"} → Should return IS query results
Installation
QoderWork Skills Directory
cp -r odps_is ~/.qoderwork/skills/Or place odps_is in your project's skills/ directory.
odpscmd Configuration
Edit scripts/odps_is_query.sh line 5 to set ODPS_CMD, or use environment variable:
export ODPS_CMD="/path/to/your/odpscmd"CLI Usage
ODPS_CMD=/path/to/odpscmd ./scripts/odps_is_query.sh top-storage
ODPS_CMD=/path/to/odpscmd ./scripts/odps_is_query.sh failed-tasks -d 20240101
ODPS_CMD=/path/to/odpscmd ./scripts/odps_is_query.sh custom 'SELECT ...'Supported types: tables, top-storage, columns, partitions, failed-tasks, cu-hours, cost-by-owner, cost-by-type, quota-usage, permissions, permission-audit, user-roles, comment-coverage, tunnel-daily, zombie-tables, smoke-test, custom.
MCP vs odpscmd Feature Matrix
| Feature | MCP | odpscmd |
|---|---|---|
| IS metadata query | execute_sql + hints | SET flag + SQL |
| Table listing | list_tables (structured) | SQL query |
| Table schema | get_table_schema (with sqlTableRef) | DESC command |
| Partition info | get_partition_info | SQL query |
| Cross-project search | search_meta_data | Not available |
| Cost estimation | cost_sql (user tables & IS views) | Not available |
| DDL/DML | create_table/insert_values (limited) | Full support |
| Result format | JSON (sync) or JSON/CSV (async) | Plain text |
| Result limit | 1000 rows (sync), unlimited (async) | Unlimited |
| Async execution | Supported | Not supported |
Metrics Reference
Related: verified-queries.md, views-reference.md, SKILL.md
All metrics with SQL expressions. Query INFORMATION_SCHEMA views with SET odps.namespace.schema=true;.
Storage Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
storage_bytes | Storage Usage | bytes | TABLES | SUM(COALESCE(data_length, 0)) |
total_storage_tb | Total Storage | TB | TABLES | SUM(COALESCE(data_length, 0)) / 1024 / 1024 / 1024 / 1024 |
partition_count | Partition Count | count | PARTITIONS | COUNT(DISTINCT partition_name) |
avg_partition_count | Avg Partitions per Table | count | PARTITIONS | AVG(partition_count) |
zombie_table_count | Zombie Tables (>90d unmodified) | count | TABLES | COUNT(CASE WHEN DATEDIFF(GETDATE(), COALESCE(last_access_time, last_modified_time), 'dd') > 90 THEN 1 END) |
stale_table_count | Stale Table Count (>30d unmodified) | count | TABLES | COUNT(CASE WHEN DATEDIFF(GETDATE(), COALESCE(last_access_time, last_modified_time), 'dd') > 30 THEN 1 END) |
Cost Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
task_count | Task Count | count | TASKS_HISTORY | COUNT(*) |
failed_task_count | Failed Task Count | count | TASKS_HISTORY | SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) |
task_failure_rate | Task Failure Rate | percent | TASKS_HISTORY | SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) |
running_task_count | Running Task Count | count | TASKS | COUNT(*) |
avg_task_duration | Avg Task Duration | seconds | TASKS_HISTORY | AVG(DATEDIFF(end_time, start_time, 'ss')) |
p99_task_duration | P99 Task Duration | seconds | TASKS_HISTORY | PERCENTILE(DATEDIFF(end_time, start_time, 'ss'), 0.99) |
task_cost_proxy | Task Cost Proxy | bytes | TASKS_HISTORY | SUM(COALESCE(input_bytes, 0)) |
cu_hour_consumed | CU-Hour Consumed | CU*hour | TASKS_HISTORY | SUM(cost_cpu) / 100.0 / 3600 |
Important notes:
cost_cpuis DOUBLE type, unit = 100 core seconds. Convert to CU-hours:SUM(cost_cpu) / 100.0 / 3600cost_memis DOUBLE type, unit = MB * seconds- TASKS_HISTORY status values:
Terminated(normal finish),Failed,Cancelled - TABLES table_type values:
MANAGED_TABLE,VIRTUAL_VIEW,EXTERNAL_TABLE,MATERIALIZED_VIEW,METADATA_TABLE,OBJECT_TABLE
Permission Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
grant_count | Grant Count | count | TABLE_PRIVILEGES | COUNT(*) |
label_protected_table_count | Label-Protected Table Count | count | TABLE_LABELS | COUNT(DISTINCT table_name) |
column_level_privilege_count | Column-Level Privilege Count | count | COLUMN_PRIVILEGES | COUNT(*) |
admin_role_user_count | Admin Role User Count | count | USER_ROLES | COUNT(DISTINCT user_name) WHERE role_name IN ('super_administrator', 'admin') |
Governance Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
column_comment_coverage | Column Comment Coverage | percent | COLUMNS | COUNT(CASE WHEN column_comment IS NOT NULL AND column_comment != '' THEN 1 END) * 100.0 / COUNT(*) |
table_comment_coverage | Table Comment Coverage | percent | TABLES | COUNT(CASE WHEN table_comment IS NOT NULL AND table_comment != '' THEN 1 END) * 100.0 / COUNT(*) |
Note: COLUMNS view has NO time field (last_modified_time exists in TABLES/PARTITIONS only). column_comment_coverage can only be computed as a static snapshot, not as a time-series metric.
Hotness Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
table_hotness_score | Table Hotness Score | score | TASKS_HISTORY | COUNT(*) appearances in input_tables/output_tables |
table_access_count | Table Access Count | count | TABLE_ACCESS_INFO | SUM(access_count) |
partition_access_count | Partition Access Count | count | PARTITION_ACCESS_INFO | SUM(access_count) |
Tunnel Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
daily_tunnel_volume | Daily Tunnel Volume | bytes | TUNNELS_HISTORY | SUM(data_size) grouped by ds |
Quota Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
quota_cpu_usage_ratio | Elastic CPU Usage Ratio | percent | QUOTA_USAGE | cpu_elastic_quota_used * 100.0 / NULLIF(cpu_elastic_quota_max, 0) |
quota_mem_usage_ratio | Elastic Memory Usage Ratio | percent | QUOTA_USAGE | mem_elastic_quota_used * 100.0 / NULLIF(mem_elastic_quota_max, 0) |
quota_reserved_cpu_usage_ratio | Reserved CPU Usage Ratio | percent | QUOTA_USAGE | cpu_quota_used * 100.0 / NULLIF(cpu_quota_max, 0) |
quota_reserved_mem_usage_ratio | Reserved Memory Usage Ratio | percent | QUOTA_USAGE | mem_quota_used * 100.0 / NULLIF(mem_quota_max, 0) |
quota_count | Quota Group Count | count | QUOTA_USAGE | COUNT(DISTINCT name) |
Object Count Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
catalog_count | Project Count | count | CATALOGS | COUNT(DISTINCT catalog_name) |
schema_count | Schema Count | count | SCHEMAS | COUNT(DISTINCT schema_name) |
package_count | Installed Package Count | count | INSTALLED_PACKAGES | COUNT(DISTINCT package_name) |
udf_count | UDF Count | count | UDFS | COUNT(DISTINCT udf_name) |
resource_count | Resource Count | count | RESOURCES | COUNT(DISTINCT resource_name) |
Advanced Task Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
input_records_total | Total Input Records | count | TASKS_HISTORY | SUM(COALESCE(input_records, 0)) |
output_records_total | Total Output Records | count | TASKS_HISTORY | SUM(COALESCE(output_records, 0)) |
io_ratio | I/O Record Ratio | ratio | TASKS_HISTORY | SUM(output_records) * 1.0 / NULLIF(SUM(input_records), 0) |
sql_complexity_avg | Avg SQL Complexity | score | TASKS_HISTORY | AVG(complexity) |
task_count_by_type | Task Count by Type | count | TASKS_HISTORY | COUNT(*) GROUP BY task_type |
cost_by_task_type | Cost by Task Type | CU*hour | TASKS_HISTORY | SUM(cost_cpu) / 100.0 / 3600 GROUP BY task_type |
Storage Tier Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
standard_storage_bytes | Standard Storage Bytes | bytes | TABLES | SUM(COALESCE(data_length, 0)) WHERE storage_tier = 'standard' |
lowfreq_storage_bytes | Low-Frequency Storage Bytes | bytes | TABLES | SUM(COALESCE(data_length, 0)) WHERE storage_tier = 'lowfrequency' |
longterm_storage_bytes | Long-Term Storage Bytes | bytes | TABLES | SUM(COALESCE(data_length, 0)) WHERE storage_tier = 'longterm' |
storage_tier_distribution | Storage Tier Distribution | bytes | TABLES | storage_tier, COUNT(*), SUM(data_length) GROUP BY storage_tier |
extreme_storage_bytes | Extreme Storage Bytes | bytes | TABLES | SUM(COALESCE(data_length, 0)) WHERE table_exstore_type IS NOT NULL |
Cluster Table Metrics
| Metric ID | Metric Name | Unit | Data Source | SQL Expression |
|---|---|---|---|---|
cluster_table_count | Cluster Table Count | count | TABLES | COUNT(*) WHERE cluster_type IS NOT NULL |
hash_cluster_count | Hash Cluster Table Count | count | TABLES | COUNT(*) WHERE cluster_type = 'HASH' |
range_cluster_count | Range Cluster Table Count | count | TABLES | COUNT(*) WHERE cluster_type = 'RANGE' |
Alert Thresholds
| Metric | Warning | Critical | Description |
|---|---|---|---|
zombie_table_count | >100 | >500 | Tables unaccessed for 90+ days |
task_failure_rate | >10% | >25% | Daily task failure rate |
daily_cu_hours | >1000 | >5000 | Daily CU-hour consumption |
Playbook Reference
Related: causal-templates.md, verified-queries.md, SKILL.md
Diagnostic scenarios for common operational concerns. Each playbook provides: intent signals, required tables, preferred metrics/dimensions, and suggested queries.
1. Storage Pressure (storage_pressure)
Intent signals: "存储满了", "storage full", "space pressure", "磁盘不够", "storage trend", "storage growth"
Required tables: TABLES, PARTITIONS
Key metrics: total_storage_tb, storage_bytes, partition_count, zombie_table_count, stale_table_count
MCP Quick Path: list_tables -> browse by size -> execute_sql + hints={"odps.namespace.schema":"true"} for aggregate queries
SQL Path / Check sequence: 1. Total storage: SELECT SUM(COALESCE(data_length, 0)) / 1024 / 1024 / 1024 / 1024 AS total_tb FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES; 2. Top tables by size: Top 20 tables by data_length 3. Zombie tables: Tables not modified in 90+ days 4. Partition explosion risk: Tables with >500 partitions 5. Stale tables: Tables not modified in 30+ days
Suggested prompt: "Analyze storage usage. Show top tables by size, identify zombie tables, and check for partition explosion risks."
2. Cost Pressure (cost_pressure)
Intent signals: "费用太高", "cost too high", "compute cost", "CU消耗大", "扫描成本", "资源消耗"
Required tables: TASKS_HISTORY
Key metrics: cu_hour_consumed, task_cost_proxy, task_count, task_failure_rate
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} (async recommended for 7+ day ds range)
SQL Path / Check sequence: 1. Daily CU-hour trend: Group by ds 2. Top cost tasks: By cost_cpu descending 3. Cost breakdown by owner: GROUP BY owner_name 4. Cost breakdown by task type: GROUP BY task_type 5. Cost breakdown by project: GROUP BY task_catalog
Suggested prompt: "Analyze compute costs. Show daily CU-hour trend, top cost consumers, and breakdown by owner and task type."
3. Task Failure Spike (task_failure_spike)
Intent signals: "任务失败", "job failed", "error rate", "执行失败", "失败率升高", "作业异常"
Required tables: TASKS_HISTORY
Key metrics: failed_task_count, task_failure_rate, task_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} -> check_access to verify permissions
SQL Path / Check sequence: 1. Daily failure count and rate: SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) 2. Failure breakdown by task_type 3. Failure breakdown by owner_name 4. Top failed tasks with error details (result field)
Suggested prompt: "Analyze task failures. Show failure rate trend, breakdown by type and owner, and list top failed tasks."
4. Permission Audit (permission_audit)
Intent signals: "权限审计", "who has access", "permission review", "安全审计", "高危授权", "越权风险"
Required tables: TABLE_PRIVILEGES, USERS, ROLES, USER_ROLES, COLUMNS, COLUMN_PRIVILEGES
Key metrics: grant_count, column_level_privilege_count, label_protected_table_count, admin_role_user_count
MCP Quick Path: check_access -> execute_sql + hints={"odps.namespace.schema":"true"} for privilege details
SQL Path / Check sequence: 1. Total grant count 2. Permission exposure per table: COUNT(DISTINCT user_name) per table 3. Column-level privileges 4. Admin role users: USER_ROLES WHERE role_name IN ('super_administrator', 'admin') 5. Users without roles (orphan users)
Suggested prompt: "Audit permissions. Show grant distribution, column-level privileges, and identify users without roles."
5. Hot Table Analysis (hot_table_analysis)
Intent signals: "热表", "most accessed table", "频繁访问的表", "热点表"
Required tables: TASKS_HISTORY, TABLES, TABLE_ACCESS_INFO
Key metrics: table_access_count, table_hotness_score
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for access pattern analysis (async recommended for 7+ day ds range)
SQL Path / Check sequence: 1. Tables by access frequency from TABLE_ACCESS_INFO 2. Top 10 most accessed tables from TASKS_HISTORY input_tables 3. Hot tables with storage sizes (join TABLES) 4. Zombie tables (not accessed in 90+ days)
Suggested prompt: "Find the most accessed tables. Show top 10 by query frequency and their storage sizes."
6. Metadata Governance Gap (metadata_governance_gap)
Intent signals: "注释覆盖率", "comment coverage", "governance gap", "元数据治理"
Required tables: TABLES, COLUMNS
Key metrics: table_comment_coverage, column_comment_coverage
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for coverage metrics
SQL Path / Check sequence: 1. Table comment coverage percentage 2. Column comment coverage percentage 3. Tables missing comments 4. Columns missing comments
Suggested prompt: "Check metadata governance. Show table and column comment coverage, list tables/columns missing comments."
7. Task Performance (task_performance)
Intent signals: "任务慢", "slow query", "performance", "执行时间长"
Required tables: TASKS_HISTORY
Key metrics: avg_task_duration, p99_task_duration, task_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} (async recommended for large ds range)
SQL Path / Check sequence: 1. Top 20 longest running tasks: ORDER BY DATEDIFF(end_time, start_time, 'ss') DESC 2. P99 duration by task type 3. Tasks with high cost_cpu but low input_bytes (inefficient)
Suggested prompt: "Analyze task performance. Show top 20 slowest tasks, P99 duration by type, and identify inefficient queries."
8. Data Transfer Audit (data_transfer_audit)
Intent signals: "下载审计", "tunnel audit", "data export", "数据传输", "公网下载"
Required tables: TUNNELS_HISTORY
Key metrics: daily_tunnel_volume (SUM(data_size))
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} -> async recommended for tunnel history queries
SQL Path / Check sequence: 1. Daily tunnel volume trend: SUM(data_size) GROUP BY ds 2. Top downloads by data_size: ORDER BY data_size DESC 3. Public IP download tracing: GROUP BY client_ip for DOWNLOAD operations 4. Failed tunnel transfers
Suggested prompt: "Audit data transfers. Show daily tunnel volume trend, top downloads, and trace public IP access."
9. User Role Audit (user_role_audit)
Intent signals: "用户角色", "user roles", "role matrix", "角色分配"
Required tables: USERS, ROLES, USER_ROLES
Key metrics: admin_role_user_count
MCP Quick Path: check_access -> execute_sql + hints={"odps.namespace.schema":"true"} for role matrix
SQL Path / Check sequence: 1. User-role matrix: JOIN USER_ROLES with ROLES 2. Users with multiple roles 3. Roles with no users (orphan roles) 4. Admin/super_administrator users
Suggested prompt: "Show user-role matrix. Identify users with excessive roles and orphan roles."
10. Partition Lifecycle (partition_lifecycle)
Intent signals: "分区太多", "partition explosion", "分区治理"
Required tables: PARTITIONS, TABLES
Key metrics: partition_count, avg_partition_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for partition queries -> list_tables for context
SQL Path / Check sequence: 1. Tables with most partitions: GROUP BY table_name HAVING COUNT > 500 2. Partition count by storage_tier 3. Small partitions (<1MB) 4. Partitions with lifecycle_enabled = false
Suggested prompt: "Analyze partition usage. Show tables with most partitions, identify small partitions, and check lifecycle settings."
11. Quota Resource Monitoring (quota_resource_monitoring)
Intent signals: "quota 使用", "资源使用率", "CPU利用率", "内存使用", "配额监控"
Required tables: QUOTA_USAGE
Key metrics: quota_cpu_usage_ratio, quota_mem_usage_ratio, quota_reserved_cpu_usage_ratio
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for quota usage queries
SQL Path / Check sequence: 1. Current elastic CPU and memory usage: cpu_elastic_quota_used / cpu_elastic_quota_max 2. Reserved CPU and memory usage: cpu_quota_used / cpu_quota_max 3. Quotas approaching limits (>80%) 4. Usage trend over time by region
Suggested prompt: "Monitor quota usage. Show current CPU and memory utilization by quota group."
12. Package Management (package_management)
Intent signals: "package 审计", "package audit", "包管理", "共享包"
Required tables: INSTALLED_PACKAGES, PACKAGE_OBJECTS, PACKAGE_PRIVILEGES
Key metrics: package_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for package inventory and privileges
SQL Path / Check sequence: 1. Installed packages by project 2. Package object types distribution 3. Package privilege audit
Suggested prompt: "Audit installed packages. Show package distribution by project and their permissions."
13. UDF Management (udf_management)
Intent signals: "UDF 审计", "UDF audit", "自定义函数", "函数管理"
Required tables: UDFS, UDF_RESOURCES, UDF_PRIVILEGES
Key metrics: udf_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for UDF inventory and dependencies
SQL Path / Check sequence: 1. UDF list by project 2. UDF resource dependencies 3. UDF privilege audit
Suggested prompt: "Audit UDFs. Show UDF list, resource dependencies, and permissions."
14. Resource Audit (resource_audit)
Intent signals: "资源审计", "resource audit", "资源管理"
Required tables: RESOURCES, RESOURCE_PRIVILEGES
Key metrics: resource_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for resource inventory and privileges
SQL Path / Check sequence: 1. Resource list by type (jar, archive, table, py) 2. Resource privilege audit 3. Temporary resources
Suggested prompt: "Audit resources. Show resource distribution by type and their permissions."
15. Catalog & Schema Overview (catalog_schema_overview)
Intent signals: "项目概览", "project overview", "schema 结构", "组织"
Required tables: CATALOGS, SCHEMAS
Key metrics: catalog_count, schema_count
MCP Quick Path: list_projects -> list_schemas -> execute_sql + hints={"odps.namespace.schema":"true"} for settings audit
SQL Path / Check sequence: 1. Project list with status and region 2. Schema organization per project 3. Project settings audit (backup, IP whitelist, cost limits)
Suggested prompt: "Show project and schema overview. Include project settings and status."
16. Data Security LABEL (data_security_label)
Intent signals: "安全标签", "label audit", "LABEL 管理", "数据安全"
Required tables: TABLE_LABELS, COLUMN_LABELS, TABLE_LABEL_GRANTS, COLUMN_LABEL_GRANTS
Key metrics: label_protected_table_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for LABEL inventory and grant queries
SQL Path / Check sequence: 1. Tables with LABEL protection 2. Columns with LABEL protection 3. LABEL grant distribution 4. Expired LABEL grants
Suggested prompt: "Audit LABEL security. Show protected tables/columns and grant distribution."
17. Access Pattern Analysis (access_pattern_analysis)
Intent signals: "访问模式", "access pattern", "访问频率", "热点分析"
Required tables: TABLE_ACCESS_INFO, PARTITION_ACCESS_INFO, TASKS_HISTORY
Key metrics: table_access_count, partition_access_count
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for access frequency analysis (async recommended for 7+ day ds range)
SQL Path / Check sequence: 1. Table access frequency by project 2. Partition access hotspots 3. Access pattern by time (daily trend)
Suggested prompt: "Analyze access patterns. Show table access frequency and partition hotspots."
18. Real-time Task Monitoring (realtime_task_monitoring)
Intent signals: "实时任务", "running tasks", "当前任务", "监控"
Required tables: TASKS (live view, Preview)
Key metrics: running_task_count
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for live task queries (TASKS view)
SQL Path / Check sequence: 1. Currently running tasks with CPU/memory usage 2. Tasks waiting in queue 3. Resource usage by quota
Suggested prompt: "Show currently running tasks. Include CPU and memory usage."
19. Data Lineage Tracking (data_lineage_tracking) [NEW]
Intent signals: "数据血缘", "lineage", "上下游依赖", "影响面", "表依赖"
Required tables: TASKS_HISTORY
Key metrics: table_hotness_score (based on input_tables/output_tables)
MCP Quick Path: execute_sql + hints={"odps.namespace.schema":"true"} for lineage queries on input_tables/output_tables (async recommended for large ds range)
SQL Path / Check sequence: 1. Upstream tables for a given table (appearing in input_tables) 2. Downstream tables for a given table (appearing in output_tables) 3. Full dependency chain for critical tables 4. Tables with most dependencies
Suggested prompt: "Trace data lineage for table X. Show upstream and downstream dependencies."
20. Storage Tier Analysis (storage_tier_analysis) [NEW]
Intent signals: "存储分层", "storage tier", "低频存储", "长期存储", "极限存储"
Required tables: TABLES, PARTITIONS
Key metrics: storage_bytes by storage_tier
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for storage tier distribution
SQL Path / Check sequence: 1. Data distribution by storage_tier (standard/lowfrequency/longterm) 2. Tables eligible for tier migration 3. Extreme storage tables (table_exstore_type) 4. Cost savings from tier optimization
Suggested prompt: "Analyze storage tier distribution. Show data by tier and migration opportunities."
21. Project Configuration Audit (project_config_audit) [NEW]
Intent signals: "项目配置", "project settings", "备份配置", "IP白名单", "安全配置"
Required tables: CATALOGS
Key metrics: catalog_count with settings
MCP Quick Path: list_projects -> execute_sql + hints={"odps.namespace.schema":"true"} for CATALOGS settings audit
SQL Path / Check sequence: 1. Backup retention: get_json_object(json_parse(settings), '$."odps.timemachine.retention.days"') 2. IP whitelist audit: get_json_object(json_parse(settings), '$."odps.security.ip.whitelist"') 3. SQL cost limits: get_json_object(json_parse(settings), '$."odps.sql.metering.value.max"') 4. Projects missing backup configuration
Suggested prompt: "Audit project configurations. Check backup settings, IP whitelists, and cost limits."
22. Extreme Storage Analysis (extreme_storage_analysis)
Intent signals: "极限存储", "extreme storage", "exstore", "极限存储表", "存储压缩"
Required tables: TABLES
Key metrics: extreme_storage_bytes, storage_bytes
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for EXSTORE table analysis
SQL Path / Check sequence: 1. Tables with extreme storage: WHERE table_exstore_type IN ('EXSTORE_TABLE_VIRTUAL', 'EXSTORE_TABLE_PHYSICAL') 2. Virtual vs physical table ratio 3. Storage savings from extreme storage compression 4. Projects using extreme storage
Suggested prompt: "Analyze extreme storage usage. Show tables using EXSTORE and their storage savings."
23. Cluster Table Analysis (cluster_table_analysis)
Intent signals: "聚簇表", "cluster table", "HASH聚簇", "RANGE聚簇", "分桶表", "bucket"
Required tables: TABLES, PARTITIONS
Key metrics: cluster_table_count, hash_cluster_count, range_cluster_count
MCP Quick Path: list_tables -> execute_sql + hints={"odps.namespace.schema":"true"} for cluster type distribution and bucket analysis
SQL Path / Check sequence: 1. Cluster type distribution: GROUP BY cluster_type (HASH/RANGE) 2. Tables with optimal bucket count: WHERE number_buckets > 0 3. Large tables without clustering: WHERE cluster_type IS NULL AND data_length > threshold 4. Bucket count distribution by cluster_type
Suggested prompt: "Analyze cluster table distribution. Show HASH vs RANGE clustering and identify large tables missing cluster optimization."
RAM 权限清单
Related: SKILL.md, mcp-tools-reference.md
required_permissions
本 Skill 查询 MaxCompute Information Schema 元数据视图所需的 RAM 权限:
odps:Describe — 查询 IS 元数据视图内容 odps:Select — 读取 IS 视图数据 odps:List — 列举 information_schema 下的对象
以上权限均为只读权限,无通配符,符合最小权限原则。
授权说明
IS 视图包含租户级数据。默认仅阿里云主账号可访问。 RAM 子账号需要通过租户级角色显式授权。
仅主账号或拥有Super_Administrator/Admin角色的账号可以进行授权。
授权步骤
1. 登录 MaxCompute 控制台,选择地域 2. 进入 管理配置 > 租户管理 3. 在 角色管理 标签页创建新角色,使用下方 Policy 模板 4. 在 用户管理 标签页添加成员并分配角色
Policy 模板
{
"Statement":[
{
"Action":["odps:Describe", "odps:Select"],
"Effect":"Allow",
"Resource":["acs:odps:*:catalogs/system_catalog/schemas/information_schema/tables/*"]
},
{
"Action":["odps:List"],
"Effect":"Allow",
"Resource":["acs:odps:*:catalogs/system_catalog/schemas/information_schema"]
}
],
"Version":"1"
}注意事项
- Resource 目标为
catalogs/system_catalog/schemas/information_schema/tables/*,非 project 级资源 - 这是租户级角色绑定 — 在租户管理中配置,非 project 级
SYSTEM_CATALOGproject 为只读;查询必须从同一地域的普通 project 发起
Terminology Dictionary
Related: entities.md, metrics.md, SKILL.md
59 terms for NL2SQL intent recognition, organized by type: metric (22), dimension (6), and table (31).
Metric Terms
| Term | Synonyms | Binding |
|---|---|---|
| 存储占用 | 存储大小、空间占用、表大小、存储量、storage size, storage usage | 数据源: TABLES |
| 表热度 | 热点表、高频访问表、热表、访问频繁、查询最多 | 数据源: TASKS_HISTORY |
| 任务失败率 | 作业失败率、失败比例、失败最多、失败趋势 | 数据源: TASKS_HISTORY |
| 新鲜度 | 数据滞后、时效性、分区新鲜度 | 数据源: PARTITIONS 列: last_modified_time |
| 任务CPU消耗 | cpu时间、CPU时间、CPU消耗 | 数据源: TASKS_HISTORY |
| 任务执行时长 | 运行时长、执行时长、墙钟时间、作业时长、任务耗时 | 数据源: TASKS_HISTORY |
| input_bytes | 输入字节、输入数据量、读取数据量 | 数据源: TASKS_HISTORY |
| output_bytes | 输出字节、输出数据量、写出数据量 | 数据源: TASKS_HISTORY |
| data_length | 数据量、数据存储大小、表数据量 | 数据源: TABLES |
| lifecycle | 生命周期、自动回收天数、TTL | 数据源: TABLES |
| last_modified_time | 最后修改时间、最近更新时间 | 数据源: TABLES 列: last_modified_time (DATETIME) |
| 排队等待 | 排队时间、等待时间 | INFORMATION_SCHEMA 视图中无此字段,无法直接查询排队时间。TASKS_HISTORY 仅有 start_time/end_time,不含排队起止时间。 |
| upload_bytes | 上传量、上传字节、上传数据量 | 数据源: TUNNELS_HISTORY |
| download_bytes | 下载量、下载字节、下载数据量 | 数据源: TUNNELS_HISTORY |
| partition_lifecycle | 分区生命周期、分区管理、分区清理 | 数据源: PARTITIONS |
| CU时 | CU时消耗、CU消耗、CU*hour, CU小时 | 数据源: TASKS_HISTORY |
| Quota CPU使用率 | CPU配额使用率、计算资源使用、CPU资源消耗 | 数据源: QUOTA_USAGE |
| Quota 内存使用率 | 内存配额使用率、内存资源使用、内存消耗 | 数据源: QUOTA_USAGE |
| 任务内存消耗 | 内存消耗、mem消耗 | 数据源: TASKS_HISTORY |
| MCP执行 | MCP查询、结构化API、MCP工具 | 非SQL指标 — 通过 maxcompute-catalog MCP 工具执行查询或获取元数据 |
| 成本预估 | cost_sql、费用预估、CU预估 | 非SQL指标 — MCP cost_sql 工具估算执行CU,支持用户表和 IS 视图(2026-04 验证) |
| 元数据浏览 | 表列表(MCP)、列信息(MCP)、分区信息(MCP) | 非SQL指标 — MCP 结构化 API(list_tables / get_table_schema / get_partition_info)获取元数据,无需写SQL |
Dimension Terms
| Term | Synonyms | Description |
|---|---|---|
| 权限暴露 | 授权暴露、高危授权、越权风险 | 表权限授权范围、主体数量与权限类型组合形成的风险视角 |
| 僵尸表 | 无效表、废弃表 | 长时间未被访问且无下游依赖的表 |
| 通道类型 | 通道类型、传输类型 | 数据通道类型,包括 UPLOAD 和 DOWNLOAD |
| 角色分配 | 角色分配、用户角色、权限分配 | 用户角色分配关系 |
| 数据血缘 | 血缘追踪、数据依赖、上下游关系、血缘分析、表血缘 | 基于 TASKS_HISTORY 的 input_tables/output_tables 追踪表级数据依赖关系 |
| 项目配置 | 项目设置、CATALOGS设置、项目安全配置、备份配置、IP白名单 | CATALOGS.settings 字段中存储的 JSON 格式项目配置 |
Table Terms
| Term | Synonyms | Description |
|---|---|---|
| CATALOGS | 项目列表、Catalog视图、项目信息 | MaxCompute INFORMATION_SCHEMA 项目列表视图 |
| CATALOG_PRIVILEGES | 项目权限、项目级权限、Catalog权限 | 项目级的权限授权信息 |
| SCHEMAS | Schema列表、Schema信息、数据库 | 项目下 Schema 信息 |
| TABLES | 表信息、表列表、表元数据 | 各个项目下的表信息 |
| COLUMNS | 字段信息、列信息、字段列表 | 各个项目下的表字段信息 |
| TABLE_ACCESS_INFO | 表访问统计、表访问信息、访问频率 | 各个项目下表的访问统计信息 |
| TABLE_LABELS | 表LABEL、表标签、表安全标签 | 各个项目下表的 LABEL 信息 |
| TABLE_LABEL_GRANTS | LABEL授权、标签授权、表标签授权 | LABEL 授权信息 |
| TABLE_PRIVILEGES | 表权限、表授权、表级权限 | 各个项目下表的权限信息 |
| COLUMN_LABELS | 字段LABEL、列标签、字段安全标签 | 各个项目下表字段级的 LABEL 信息 |
| COLUMN_LABEL_GRANTS | 字段LABEL授权、列标签授权 | 各个项目下表字段的 LABEL 授权信息 |
| COLUMN_PRIVILEGES | 字段权限、列权限、字段级权限 | 各个项目下表字段级的权限信息 |
| PARTITIONS | 分区信息、分区列表、表分区 | 各个项目下的表分区信息 |
| PARTITION_ACCESS_INFO | 分区访问统计、分区访问信息、分区热度 | 各个项目下表分区的访问统计信息 |
| USERS | 用户列表、用户信息、账号列表 | 用户列表 |
| ROLES | 角色列表、角色信息、权限角色 | 各个项目级别以及账号级别的角色列表 |
| USER_ROLES | 用户角色、用户角色关系、角色分配 | 用户拥有的角色信息 |
| INSTALLED_PACKAGES | 已安装Package、包列表、Package信息 | 各个项目下已安装的 Package 信息 |
| PACKAGE_PRIVILEGES | Package权限、包权限、Package授权 | Package 的授权信息 |
| PACKAGE_OBJECTS | Package对象、包对象、Package内容 | Package 中的对象信息 |
| UDFS | UDF列表、自定义函数、UDF信息 | 各个项目下的 UDF 信息 |
| UDF_PRIVILEGES | UDF权限、函数权限、UDF授权 | 各个项目下的 UDF 授权信息 |
| UDF_RESOURCES | UDF资源、函数资源依赖、UDF依赖 | 各个项目下 UDF 的资源依赖 |
| RESOURCES | 资源列表、资源信息、资源文件 | 各个项目下的资源信息 |
| RESOURCE_PRIVILEGES | 资源权限、资源授权、资源访问权限 | 各个项目下资源的权限信息 |
| TASKS | 运行中任务、实时任务、当前任务、任务快照 | 运行中作业的实时快照,用于实时监控作业 |
| TASKS_HISTORY | 任务历史、作业历史、历史任务 | 各个项目内已完成的作业历史,保留近 14 天数据 |
| TUNNELS_HISTORY | 数据通道历史、Tunnel历史、传输历史 | 数据通道批量上传下载的历史数据,保留近 14 天数据 |
| QUOTA_USAGE | Quota使用量、资源配额使用、配额监控、Quota监控 | 包年包月计算 Quota 的资源使用实时快照 |
| VOLUMES | Volume列表、Volume信息、外部存储 | MaxCompute Volume 视图 |
| FOREIGN_SERVERS | ForeignServer、外部服务器、外部数据源 | MaxCompute ForeignServer 视图 |
Troubleshooting Guide
Related: SKILL.md, ram-policies.md, mcp-tools-reference.md
Detailed error identification and recovery procedures for ODPS Information Schema queries.
T1: "Table not found" on IS Views
Error signal:
SemanticAnalysException: Table not found: SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLESRoot cause: Missing odps.namespace.schema=true flag. Without it, MaxCompute cannot resolve the cross-project SYSTEM_CATALOG reference.
Fix — MCP:
execute_sql(
sql="SELECT ... FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES ...",
hints={"odps.namespace.schema": "true"}
)Fix — odpscmd:
SET odps.namespace.schema=true;
SELECT ... FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES ...;Verification: Run Q30 smoke test:
SET odps.namespace.schema=true;
SELECT COUNT(*) AS table_count FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES LIMIT 1;If this returns a count, the flag is working.
---
T2: "Access denied" / "Permission denied" on IS Views
Error signal:
ODPS-0130131: Authorization failed -- user XXX does not have SELECT privilege on table SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLESRoot cause: Current user lacks tenant-level IS access role. Only Alibaba Cloud primary account has access by default; RAM sub-accounts need explicit role assignment.
Fix: See ram-policies.md for the complete Policy template and authorization steps. Summary:
1. Log in to MaxCompute Console → 管理配置 > 租户管理 2. Create role with odps:Describe + odps:Select on information_schema/tables/* and odps:List on information_schema 3. Assign user to the role
---
T3: TASKS_HISTORY Query Slow or Expensive
Error signal: Query takes >60s, or cost_sql returns high CU estimate.
Root cause: Missing ds partition filter. TASKS_HISTORY is partitioned by ds (date string YYYYMMDD). Without it, the engine scans all 14 days of data.
Fix: Always add a ds filter:
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd')Pre-check: Use cost_sql before executing (supports IS views, verified 2026-04):
cost_sql(
sql="SELECT ... FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds >= '20260401' ...",
hints={"odps.namespace.schema": "true"}
)---
T4: MCP Returns Exactly 1000 Rows
Error signal: execute_sql returns rowCount: 1000 — this indicates sync mode truncation.
Root cause: MCP sync mode (async=false) has a 1000-row limit. The actual result may be larger.
Fix — Option A (recommended): Re-run with async mode:
instance_id = execute_sql(sql=..., hints={"odps.namespace.schema": "true"}, async=True)
# Poll until complete
get_instance_status(instance_id)
# Retrieve full results
get_instance(instance_id)Fix — Option B: Add tighter WHERE/LIMIT:
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
LIMIT 500---
T5: "Column not found" Error
Error signal:
SemanticAnalysException: Column not found: size_bytesRoot cause: Used a non-existent column name. Common mistakes documented in SKILL.md Critical Column Reference.
Most common wrong columns and their correct replacements:
| Wrong Column | Correct Column | Context |
|---|---|---|
size_bytes | data_length | TABLES table size |
task_status | status | TASKS_HISTORY |
task_owner | owner_name | TASKS_HISTORY submitter |
task_id | inst_id | TASKS_HISTORY instance |
error_message | result | TASKS_HISTORY error info |
duration_ms | DATEDIFF(end_time, start_time, 'ss') | Computed duration |
scan_bytes / processed_bytes | input_bytes | TASKS_HISTORY input size |
grantee | user_name / user_id | TABLE_PRIVILEGES |
comment | table_comment / column_comment | TABLES/COLUMNS |
project_name | task_catalog / table_catalog | TASKS_HISTORY/TABLES |
Fix: Replace the wrong column with the correct one from the table above.
---
T6: Async Query Timeout (>30s)
Error signal: Sync mode returns instanceId instead of results (timeout exceeded).
Root cause: Query involves large scan (e.g., TASKS_HISTORY with wide ds range, multi-table JOIN).
Fix: 1. Pre-check with `cost_sql`: Estimate CU before running 2. Add `ds` filter: Narrow the date range 3. Use async mode explicitly:
instance_id = execute_sql(sql=..., async=True, hints={"odps.namespace.schema": "true"})
# Poll with get_instance_status
# Retrieve with get_instance (no row limit in async)4. Split the query: Break a 14-day scan into two 7-day queries
---
T7: IS View Shows No Recent Data
Error signal: Query returns 0 rows for today's data.
Root cause: IS views have inherent delays:
- History views (TASKS_HISTORY, TUNNELS_HISTORY): ~5 min delay
- Realtime views (TABLES, COLUMNS, etc.): ~3 hours delay
- TASKS (live snapshot): Seconds delay (Preview feature)
Fix:
- For yesterday's data: query after 06:00 to ensure completeness
- For today's data: expect ~5 min latency for history, ~3 hours for realtime
- Use
TASKS(not TASKS_HISTORY) for live monitoring of running jobs
Verified Queries Reference
Related: metrics.md, views-reference.md, joins.md, SKILL.md
Query Index
Storage (Q1–Q4) Q1: Top 20 Tables by Storage · Q2: Storage Breakdown by Owner · Q3: Zombie Tables (Not Accessed in 90 Days) · Q4: Partition Explosion Risk
Cost (Q5–Q8) Q5: Daily CU-Hour Trend · Q6: Cost by Task Owner · Q7: Cost by Task Type · Q8: Top 20 Most Expensive Tasks
Failure (Q9–Q11) Q9: Failed Tasks Yesterday · Q10: Daily Failure Rate · Q11: Failure Breakdown by Type
Permission (Q12–Q14) Q12: Permission Exposure · Q13: Admin Role Users · Q14: User-Role Matrix
Governance (Q15–Q16) Q15: Table Comment Coverage · Q16: Column Comment Coverage
Tunnel (Q17–Q18) Q17: Daily Tunnel Volume · Q18: Top Tunnel Downloads
Object Count (Q19) Q19: Object Inventory
Performance (Q20) Q20: Top 20 Slowest Tasks
Hot Table (Q21–Q23) Q21: Top 20 Most Accessed Tables (Last 7 Days) · Q22: Top Tables by Data Volume Read (Last 7 Days) · Q23: User Resource Consumption by Table
Official Verified (Q24–Q29) Q24: TOP Storage Tables with COALESCE · Q25: Partition Explosion Risk (Simplified) · Q26: Daily Failure Trend · Q27: CU-Hour by Project and Hour · Q28: User Resource Consumption · Q29: Project Configuration Audit
Smoke Test (Q30) Q30: Namespace Flag Verification
Pre-validated SQL queries for common INFORMATION_SCHEMA analysis scenarios. All queries require SET odps.namespace.schema=true; prefix.
Storage Queries
Q1: Top 20 Tables by Storage
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT table_name, owner_name, data_length / 1024 / 1024 / 1024 AS size_gb,
lifecycle, last_modified_time
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
WHERE table_type = 'MANAGED_TABLE'
AND data_length IS NOT NULL
ORDER BY data_length DESC
LIMIT 20;Q2: Storage Breakdown by Owner
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT owner_name,
COUNT(*) AS table_count,
SUM(data_length) / 1024 / 1024 / 1024 / 1024 AS total_tb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
WHERE table_type = 'MANAGED_TABLE'
AND data_length IS NOT NULL
GROUP BY owner_name
ORDER BY total_tb DESC;Q3: Zombie Tables (Not Accessed in 90 Days)
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT table_name, owner_name, data_length / 1024 / 1024 / 1024 AS size_gb,
last_modified_time, lifecycle
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
WHERE COALESCE(last_access_time, last_modified_time) < DATEADD(GETDATE(), -90, 'dd')
AND table_type = 'MANAGED_TABLE'
AND data_length IS NOT NULL
ORDER BY data_length DESC;Q4: Partition Explosion Risk
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT table_catalog, table_schema, table_name,
COUNT(*) AS partition_count,
SUM(data_length) / 1024 / 1024 / 1024 AS size_gb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS
GROUP BY table_catalog, table_schema, table_name
HAVING COUNT(*) > 1000
ORDER BY partition_count DESC
LIMIT 20;Cost Queries
Q5: Daily CU-Hour Trend
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync OK for ds ≤3 days; MUST use async=true for ds >3 days
SELECT ds,
COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd')
GROUP BY ds
ORDER BY ds DESC
LIMIT 30;Q6: Cost by Task Owner
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT owner_name,
COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours,
SUM(cost_cpu) * 100.0 / SUM(SUM(cost_cpu)) OVER () AS cost_pct
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY owner_name
ORDER BY cu_hours DESC;Q7: Cost by Task Type
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_type,
COUNT(*) AS task_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY task_type
ORDER BY cu_hours DESC;Q8: Top 20 Most Expensive Tasks
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_name, task_type, owner_name, start_time,
cost_cpu / 100.0 / 3600 AS cu_hours,
DATEDIFF(end_time, start_time, 'ss') AS run_seconds
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
ORDER BY cost_cpu DESC
LIMIT 20;Failure Queries
Q9: Failed Tasks Yesterday
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_catalog, task_name, task_type, inst_id, owner_name, start_time, end_time,
result,
cost_cpu / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
AND status = 'Failed'
ORDER BY start_time DESC;Q10: Daily Failure Rate
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync OK for ds ≤3 days; MUST use async=true for ds >3 days
SELECT ds,
COUNT(*) AS total_tasks,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) AS failed_tasks,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS failure_rate
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd')
GROUP BY ds
ORDER BY ds DESC
LIMIT 14;Q11: Failure Breakdown by Type
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_type,
COUNT(*) AS total,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) AS failed,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS failure_rate
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY task_type
ORDER BY failed DESC;Permission Queries
Q12: Permission Exposure
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT p.table_catalog, p.table_schema, p.table_name, p.user_name, p.privilege_type, t.owner_name
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES p
JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t
ON p.table_catalog = t.table_catalog AND p.table_schema = t.table_schema AND p.table_name = t.table_name
WHERE p.user_name != t.owner_name
AND (p.expired IS NULL OR p.expired > GETDATE())
ORDER BY p.table_name;Q13: Admin Role Users
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT u.user_name, u.user_id, r.role_name, ur.user_role_catalog
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.USERS u
JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.USER_ROLES ur ON u.user_id = ur.user_id AND (u.user_catalog = ur.user_role_catalog OR (u.user_catalog IS NULL AND ur.user_role_catalog IS NULL))
-- NOTE: user_role_catalog and role_catalog may be NULL for tenant-level roles;
-- the OR condition handles both project-level and tenant-level role matching.
JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.ROLES r ON ur.role_name = r.role_name AND (ur.user_role_catalog = r.role_catalog OR (ur.user_role_catalog IS NULL AND r.role_catalog IS NULL))
WHERE LOWER(r.role_name) IN ('super_administrator', 'admin')
ORDER BY u.user_name;Q14: User-Role Matrix
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT u.user_name, u.user_id, r.role_name, ur.user_role_catalog
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.USERS u
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.USER_ROLES ur ON u.user_id = ur.user_id AND (u.user_catalog = ur.user_role_catalog OR (u.user_catalog IS NULL AND ur.user_role_catalog IS NULL))
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.ROLES r ON ur.role_name = r.role_name AND (ur.user_role_catalog = r.role_catalog OR (ur.user_role_catalog IS NULL AND r.role_catalog IS NULL))
ORDER BY u.user_name, r.role_name;Governance Queries
Q15: Table Comment Coverage
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT
COUNT(CASE WHEN table_comment IS NOT NULL AND table_comment != '' THEN 1 END) AS commented,
COUNT(*) AS total,
COUNT(CASE WHEN table_comment IS NOT NULL AND table_comment != '' THEN 1 END) * 100.0 / COUNT(*) AS coverage_pct
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES;Q16: Column Comment Coverage
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT
COUNT(CASE WHEN column_comment IS NOT NULL AND column_comment != '' THEN 1 END) AS commented,
COUNT(*) AS total,
COUNT(CASE WHEN column_comment IS NOT NULL AND column_comment != '' THEN 1 END) * 100.0 / COUNT(*) AS coverage_pct
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.COLUMNS;Tunnel Queries
Q17: Daily Tunnel Volume
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync OK for ds =1 day; MUST use async=true for ds >1 day (TUNNELS_HISTORY volume >> TASKS_HISTORY)
SELECT ds,
COUNT(*) AS tunnel_count,
SUM(data_size) / 1024 / 1024 / 1024 AS volume_gb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TUNNELS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY ds
ORDER BY ds DESC
LIMIT 7;Tip: For upload/download breakdown, addoperate_typeto SELECT and GROUP BY:GROUP BY ds, operate_type
Q18: Top Tunnel Downloads
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT tunnel_catalog, object_name, operate_type,
COUNT(*) AS tunnel_count,
SUM(data_size) / 1024 / 1024 / 1024 AS volume_gb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TUNNELS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
AND operate_type IN ('DOWNLOADLOG', 'DOWNLOADINSTANCELOG')
GROUP BY tunnel_catalog, object_name, operate_type
ORDER BY volume_gb DESC
LIMIT 20;Object Count Queries
Q19: Object Inventory
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT 'Tables' AS object_type, COUNT(*) AS cnt FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES
UNION ALL
SELECT 'UDFs', COUNT(*) FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.UDFS
UNION ALL
SELECT 'Resources', COUNT(*) FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.RESOURCES
UNION ALL
SELECT 'Roles', COUNT(*) FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.ROLES
UNION ALL
SELECT 'Packages', COUNT(*) FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.INSTALLED_PACKAGES;Performance Queries
Q20: Top 20 Slowest Tasks
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_catalog, task_name, task_type, owner_name, start_time,
DATEDIFF(end_time, start_time, 'ss') AS run_seconds
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
AND status = 'Terminated'
ORDER BY run_seconds DESC
LIMIT 20;Hot Table Queries
Q21: Top 20 Most Accessed Tables (Last 7 Days)
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync may work for ds ≤3 days; MUST use async=true for ds >3 days (LATERAL VIEW EXPLODE causes row expansion)
SELECT table_name,
COUNT(*) AS access_count,
SUM(input_bytes) / 1024 / 1024 / 1024 AS total_read_gb
FROM (
SELECT input_bytes,
REGEXP_REPLACE(input_tables, '^\\[|\\]|"|\\s', '') AS table_list
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
AND input_tables IS NOT NULL AND input_tables != ''
) t
LATERAL VIEW EXPLODE(SPLIT(table_list, ',')) tbl AS table_name
WHERE table_name != ''
GROUP BY table_name
ORDER BY access_count DESC
LIMIT 20;Q22: Top Tables by Data Volume Read (Last 7 Days)
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync may work for ds ≤3 days; MUST use async=true for ds >3 days (LATERAL VIEW EXPLODE causes row expansion)
SELECT table_name,
COUNT(*) AS access_count,
SUM(input_bytes) / 1024 / 1024 / 1024 AS total_read_gb
FROM (
SELECT input_bytes,
REGEXP_REPLACE(input_tables, '^\\[|\\]|"|\\s', '') AS table_list
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
AND input_tables IS NOT NULL AND input_tables != ''
) t
LATERAL VIEW EXPLODE(SPLIT(table_list, ',')) tbl AS table_name
WHERE table_name != ''
GROUP BY table_name
ORDER BY total_read_gb DESC
LIMIT 20;Q23: User Resource Consumption by Table
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync may work for ds ≤3 days; MUST use async=true for ds >3 days (LATERAL VIEW EXPLODE causes row expansion)
SELECT owner_name, table_name,
COUNT(*) AS access_count,
SUM(input_bytes) / 1024 / 1024 / 1024 AS total_read_gb,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM (
SELECT owner_name, input_bytes, cost_cpu,
REGEXP_REPLACE(input_tables, '^\\[|\\]|"|\\s', '') AS table_list
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
AND input_tables IS NOT NULL AND input_tables != ''
) t
LATERAL VIEW EXPLODE(SPLIT(table_list, ',')) tbl AS table_name
WHERE table_name != ''
GROUP BY owner_name, table_name
ORDER BY access_count DESC;For column name pitfalls and corrections, see the Critical Column Name Reference in SKILL.md.
Official Verified Queries (Q24-Q29)
These queries use COALESCE for robustness across schema variations.
Q24: TOP Storage Tables with COALESCE
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
-- Cost warning: LEFT JOIN PARTITIONS may produce many rows for heavily partitioned tables.
-- Consider adding WHERE clause or using a subquery for partition_count instead.
SELECT
t.table_catalog,
t.table_schema,
t.table_name,
t.table_comment,
COALESCE(t.data_length, 0) AS storage_bytes,
CASE
WHEN COALESCE(t.data_length, 0) >= 1099511627776
THEN CONCAT(ROUND(COALESCE(t.data_length, 0) / 1099511627776.0, 2), ' TB')
WHEN COALESCE(t.data_length, 0) >= 1073741824
THEN CONCAT(ROUND(COALESCE(t.data_length, 0) / 1073741824.0, 2), ' GB')
ELSE CONCAT(ROUND(COALESCE(t.data_length, 0) / 1048576.0, 2), ' MB')
END AS storage_readable,
t.owner_name,
t.last_modified_time,
COUNT(DISTINCT p.partition_name) AS partition_count
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t
LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS p
ON t.table_catalog = p.table_catalog
AND t.table_schema = p.table_schema
AND t.table_name = p.table_name
GROUP BY t.table_catalog, t.table_schema, t.table_name,
t.table_comment, t.data_length,
t.owner_name, t.last_modified_time
ORDER BY storage_bytes DESC
LIMIT 20;Q25: Partition Explosion Risk (Simplified)
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT
table_catalog,
table_schema,
table_name,
COUNT(DISTINCT partition_name) AS partition_count,
MIN(create_time) AS earliest_partition,
MAX(create_time) AS latest_partition
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS
GROUP BY table_catalog, table_schema, table_name
HAVING COUNT(DISTINCT partition_name) > 500
ORDER BY partition_count DESC;Q26: Daily Failure Trend
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync OK for ds ≤3 days; MUST use async=true for ds >3 days
SELECT
ds AS stat_date,
COUNT(*) AS task_count,
SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END) AS failed_count,
ROUND(SUM(CASE WHEN status = 'Failed' THEN 1 ELSE 0 END)
* 100.0 / COUNT(*), 2) AS failure_rate_pct
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
GROUP BY ds
ORDER BY stat_date;Q27: CU-Hour by Project and Hour
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT task_catalog,
DATEPART(end_time, 'hh') AS end_hour,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds = TO_CHAR(DATEADD(GETDATE(), -1, 'dd'), 'yyyymmdd')
GROUP BY task_catalog, DATEPART(end_time, 'hh')
ORDER BY cu_hours DESC;Warning: Do NOT useTO_CHAR(end_time, 'hh')(12-hour format, AM/PM collapse) orTO_CHAR(end_time, 'hh24')(not supported in MaxCompute, outputs literal "24"). UseDATEPART(end_time, 'hh')orHOUR(end_time)which return 0-23.
Q28: User Resource Consumption
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL Execution: Sync OK for ds ≤3 days; MUST use async=true for ds >3 days
SELECT owner_name,
COUNT(*) AS query_count,
SUM(cost_cpu) / 100.0 / 3600 AS cu_hours,
SUM(cost_mem) AS mem_mb_seconds,
SUM(input_bytes) / 1024 / 1024 / 1024 AS input_gb,
SUM(output_bytes) / 1024 / 1024 / 1024 AS output_gb
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY
WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd')
GROUP BY owner_name
ORDER BY cu_hours DESC
LIMIT 100;Q29: Project Configuration Audit
MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT catalog_name, region, create_time,
get_json_object(json_parse(settings), '$."odps.timemachine.retention.days"') AS backup_days,
get_json_object(json_parse(settings), '$."odps.sql.metering.value.max"') AS sql_cost_limit
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.CATALOGS;Smoke Test
Q30: Namespace Flag Verification
Purpose: Minimal query to verify odps.namespace.schema=true is set correctly. Run this first if IS queries return "Table not found".MCP: execute_sql hints={"odps.namespace.schema":"true"} | odpscmd: SET odps.namespace.schema=true; + SQL
SELECT COUNT(*) AS table_count
FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES;#!/bin/bash
# ODPS Information Schema Query Helper
# Portable version - configure ODPS_CMD path before use
# MCP Mode:
# When maxcompute-catalog MCP is available, the AI agent should use MCP tools
# (list_tables, get_table_schema, execute_sql, etc.) instead of this script.
# This script serves as the odpscmd fallback channel.
# See references/mcp-tools-reference.md for MCP tool details.
# Configuration - modify these paths for your environment
ODPS_CMD="${ODPS_CMD:-odpscmd}" # Path to odpscmd binary, or set ODPS_CMD env var
NS_FLAG="SET odps.namespace.schema=true;"
usage() {
echo "Usage: $0 [OPTIONS] <query_type>"
echo ""
echo "Options:"
echo " -p, --project <name> Specify project"
echo " -d, --date <YYYYMMDD> Specify date for historical queries (default: yesterday)"
echo " -t, --timeout <seconds> Execution timeout in seconds (default: 300)"
echo " -h, --help Show this help"
echo ""
echo "Query types:"
echo " tables List all tables with sizes"
echo " top-storage Top 20 tables by storage"
echo " columns <table> Show columns for a table"
echo " partitions <table> Show partitions for a table"
echo " failed-tasks Failed tasks for a date"
echo " cu-hours Daily CU-hour trend"
echo " cost-by-owner Cost breakdown by owner"
echo " permissions Permission audit"
echo " user-roles User-role matrix"
echo " comment-coverage Metadata governance coverage"
echo " tunnel-daily Daily tunnel volume"
echo " zombie-tables Tables not accessed in 90 days (with NULL-safe COALESCE)"
echo " cost-by-type Cost breakdown by task type"
echo " quota-usage Top 20 users by CU hours (7-day)"
echo " permission-audit Active non-owner permissions (expired filtered)"
echo " smoke-test Minimal IS query to verify namespace flag"
echo " custom <sql> Custom SQL (auto-prepends namespace flag)"
echo ""
echo "Examples:"
echo " $0 top-storage"
echo " $0 columns my_table"
echo " $0 failed-tasks -d 20240101"
echo " $0 custom 'SELECT table_name FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES LIMIT 10;'"
}
# Default date: yesterday
DATE=$(date -v-1d '+%Y%m%d' 2>/dev/null || date -d 'yesterday' '+%Y%m%d' 2>/dev/null)
PROJECT=""
TIMEOUT=300
QUERY_TYPE=""
TABLE_NAME=""
CUSTOM_SQL=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-p|--project) PROJECT="$2"; shift 2 ;;
-d|--date) DATE="$2"; shift 2 ;;
-t|--timeout) TIMEOUT="$2"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*)
if [ -z "$QUERY_TYPE" ]; then
QUERY_TYPE="$1"
elif [ -z "$TABLE_NAME" ]; then
TABLE_NAME="$1"
fi
shift
;;
esac
done
if [ -z "$QUERY_TYPE" ]; then
usage
exit 1
fi
# Validate DATE format (YYYYMMDD)
if ! echo "$DATE" | grep -qE '^[0-9]{8}$'; then
echo "Error: invalid date format. Expected YYYYMMDD (e.g., 20240101)."
exit 1
fi
# Build SQL based on query type
case $QUERY_TYPE in
tables)
SQL="$NS_FLAG SELECT table_name, owner_name, data_length / 1024 / 1024 / 1024 AS size_gb FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES ORDER BY data_length DESC LIMIT 50;"
;;
top-storage)
SQL="$NS_FLAG SELECT table_name, owner_name, data_length / 1024 / 1024 / 1024 AS size_gb, lifecycle FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES WHERE table_type = 'MANAGED_TABLE' ORDER BY data_length DESC LIMIT 20;"
;;
columns)
if [ -z "$TABLE_NAME" ]; then echo "Error: table name required"; exit 1; fi
if ! echo "$TABLE_NAME" | grep -qE '^[a-zA-Z0-9_]{1,128}$'; then
echo "Error: invalid table name. Only letters, digits, and underscores allowed (max 128 chars)."
exit 1
fi
SQL="$NS_FLAG SELECT column_name, data_type, is_nullable, column_comment FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$TABLE_NAME' ORDER BY ordinal_position;"
;;
partitions)
if [ -z "$TABLE_NAME" ]; then echo "Error: table name required"; exit 1; fi
if ! echo "$TABLE_NAME" | grep -qE '^[a-zA-Z0-9_]{1,128}$'; then
echo "Error: invalid table name. Only letters, digits, and underscores allowed (max 128 chars)."
exit 1
fi
SQL="$NS_FLAG SELECT partition_name, data_length / 1024 / 1024 AS size_mb, create_time FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.PARTITIONS WHERE table_name = '$TABLE_NAME' ORDER BY partition_name DESC LIMIT 50;"
;;
failed-tasks)
SQL="$NS_FLAG SELECT task_name, task_type, owner_name, start_time, end_time FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds = '$DATE' AND status = 'Failed' ORDER BY start_time DESC;"
;;
cu-hours)
SQL="$NS_FLAG SELECT ds, COUNT(*) AS task_count, SUM(cost_cpu) / 100.0 / 3600 AS cu_hours FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd') GROUP BY ds ORDER BY ds DESC LIMIT 30;"
;;
cost-by-owner)
SQL="$NS_FLAG SELECT owner_name, COUNT(*) AS task_count, SUM(cost_cpu) / 100.0 / 3600 AS cu_hours FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds = '$DATE' GROUP BY owner_name ORDER BY cu_hours DESC;"
;;
permissions)
SQL="$NS_FLAG SELECT p.table_name, p.user_name, p.privilege_type, t.owner_name FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES p JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t ON p.table_catalog = t.table_catalog AND p.table_name = t.table_name WHERE p.user_name != t.owner_name ORDER BY p.table_name;"
;;
user-roles)
SQL="$NS_FLAG SELECT u.user_name, r.role_name FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.USERS u LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.USER_ROLES ur ON u.user_id = ur.user_id AND u.user_catalog = ur.user_role_catalog LEFT JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.ROLES r ON ur.role_name = r.role_name AND ur.user_role_catalog = r.role_catalog ORDER BY u.user_name, r.role_name;"
;;
comment-coverage)
SQL="$NS_FLAG SELECT 'Tables' AS entity, COUNT(CASE WHEN table_comment IS NOT NULL AND table_comment != '' THEN 1 END) AS commented, COUNT(*) AS total, COUNT(CASE WHEN table_comment IS NOT NULL AND table_comment != '' THEN 1 END) * 100.0 / COUNT(*) AS coverage_pct FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES UNION ALL SELECT 'Columns', COUNT(CASE WHEN column_comment IS NOT NULL AND column_comment != '' THEN 1 END), COUNT(*), COUNT(CASE WHEN column_comment IS NOT NULL AND column_comment != '' THEN 1 END) * 100.0 / COUNT(*) FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.COLUMNS;"
;;
tunnel-daily)
SQL="$NS_FLAG SELECT ds, COUNT(*) AS tunnel_count, SUM(data_size) / 1024 / 1024 / 1024 AS volume_gb FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TUNNELS_HISTORY WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -14, 'dd'), 'yyyymmdd') GROUP BY ds ORDER BY ds DESC LIMIT 14;"
;;
zombie-tables)
SQL="$NS_FLAG SELECT table_name, owner_name, data_length / 1024 / 1024 / 1024 AS size_gb, COALESCE(last_access_time, last_modified_time) AS last_access, lifecycle FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES WHERE COALESCE(last_access_time, last_modified_time) < DATEADD(GETDATE(), -90, 'dd') AND table_type = 'MANAGED_TABLE' AND data_length IS NOT NULL ORDER BY data_length DESC;"
;;
cost-by-type)
SQL="$NS_FLAG SELECT task_type, COUNT(*) AS task_count, SUM(cost_cpu) / 100.0 / 3600 AS cu_hours, SUM(input_bytes) / 1024 / 1024 / 1024 AS input_gb FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds = '$DATE' GROUP BY task_type ORDER BY cu_hours DESC;"
;;
quota-usage)
SQL="$NS_FLAG SELECT task_type, owner_name, SUM(cost_cpu) / 100.0 / 3600 AS cu_hours FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY WHERE ds >= TO_CHAR(DATEADD(GETDATE(), -7, 'dd'), 'yyyymmdd') GROUP BY task_type, owner_name ORDER BY cu_hours DESC LIMIT 20;"
;;
permission-audit)
SQL="$NS_FLAG SELECT p.table_name, p.user_name, p.privilege_type, t.owner_name FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLE_PRIVILEGES p JOIN SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES t ON p.table_catalog = t.table_catalog AND p.table_name = t.table_name WHERE p.user_name != t.owner_name AND (p.expired IS NULL OR p.expired > GETDATE()) ORDER BY p.table_name;"
;;
smoke-test)
SQL="$NS_FLAG SELECT COUNT(*) AS table_count FROM SYSTEM_CATALOG.INFORMATION_SCHEMA.TABLES LIMIT 1;"
;;
custom)
if [ -z "$TABLE_NAME" ]; then echo "Error: SQL required for custom query"; exit 1; fi
CUSTOM_SQL="$TABLE_NAME"
# Reject DDL/DML — custom mode only allows SELECT (DQL)
if echo "$CUSTOM_SQL" | grep -qiE '^\s*(INSERT|UPDATE|DELETE|DROP|TRUNCATE|ALTER|CREATE|GRANT|REVOKE|MERGE|LOAD|UNLOAD)\b'; then
echo "Error: DDL/DML statements are not allowed in custom mode. Only SELECT queries are supported."
exit 1
fi
# Reject SELECT * (violates no-SELECT-* rule)
if echo "$CUSTOM_SQL" | grep -qiE 'SELECT\s+\*\s+FROM'; then
echo "Error: SELECT * is not allowed. Use explicit column names."
exit 1
fi
# Check if SQL already has the namespace flag
if [[ "$CUSTOM_SQL" != *"$NS_FLAG"* ]]; then
SQL="$NS_FLAG $CUSTOM_SQL"
else
SQL="$CUSTOM_SQL"
fi
;;
*)
echo "Unknown query type: $QUERY_TYPE"
usage
exit 1
;;
esac
# Execute
CMD="$ODPS_CMD"
if [ -n "$PROJECT" ]; then
if ! echo "$PROJECT" | grep -qE '^[a-zA-Z][a-zA-Z0-9_]{2,27}$'; then
echo "Error: invalid project name. Must start with a letter, contain only letters/digits/underscores, and be 3-28 chars."
exit 1
fi
CMD="$CMD --project=$PROJECT"
fi
echo "Query type: $QUERY_TYPE"
[ -n "$PROJECT" ] && echo "Project: $PROJECT"
echo "---"
timeout "$TIMEOUT" $CMD -e "$SQL"
Related skills
FAQ
What is it for?
Metadata analysis via Information Schema views: storage stats, query history, permission audit, cost tracking, and governance diagnostics.
What must every tenant-level query include?
The namespace flag (odps.namespace.schema=true), or all queries fail with Table not found.