Skip to content

Latest commit

 

History

History
156 lines (126 loc) · 7.34 KB

File metadata and controls

156 lines (126 loc) · 7.34 KB

PG LoadSDL Scenarios

Goal: Implement func LoadSDL(sql string) (*Catalog, error) that loads declarative schema definitions with automatic dependency resolution and SDL validation. Verification: Call LoadSDL, verify catalog state matches expected. Compare with LoadSQL on correctly-ordered equivalent DDL. Reference sources: omni pg/catalog ProcessUtility, pg_dump dependency ordering, PostgreSQL DDL semantics

Status: [ ] pending, [x] passing, [~] partial (needs upstream change)


Phase 1: SDL Validation + Basic Infrastructure

1.1 SDL Validation

  • Empty string returns empty catalog with no error
  • Valid CREATE TABLE is accepted
  • Valid CREATE VIEW is accepted
  • Valid CREATE FUNCTION is accepted
  • Valid CREATE INDEX is accepted
  • Valid CREATE SEQUENCE is accepted
  • Valid CREATE SCHEMA is accepted
  • Valid CREATE TYPE (enum/domain/composite/range) is accepted
  • Valid CREATE EXTENSION is accepted
  • Valid CREATE TRIGGER is accepted
  • Valid CREATE POLICY is accepted
  • Valid CREATE MATERIALIZED VIEW is accepted
  • Valid CREATE CAST is accepted
  • Valid CREATE FOREIGN TABLE is accepted
  • Valid COMMENT ON is accepted
  • Valid GRANT is accepted
  • ALTER SEQUENCE OWNED BY is accepted
  • ALTER TABLE ENABLE ROW LEVEL SECURITY is accepted
  • ALTER TYPE ADD VALUE is accepted
  • INSERT statement is rejected with clear error
  • UPDATE statement is rejected with clear error
  • DELETE statement is rejected with clear error
  • DROP TABLE is rejected with clear error
  • ALTER TABLE ADD COLUMN is rejected with clear error
  • ALTER TABLE DROP COLUMN is rejected with clear error
  • TRUNCATE is rejected with clear error
  • DO block is rejected with clear error
  • Parse error in SDL returns error

1.2 Basic Dependency Resolution — Same Layer

  • Two tables with no dependencies load in any order
  • Table with FK to another table — FK table defined first in SDL
  • Table with FK to another table — FK table defined last in SDL (forward reference)
  • Table with column type referencing enum — enum defined after table
  • Table with column type referencing domain — domain defined after table
  • Table with column type referencing composite type — type defined after table
  • View referencing table — table defined after view
  • Index on table — table defined after index
  • Result catalog matches LoadSQL with correctly-ordered equivalent

1.3 Declared Object Collection and Name Resolution

  • Unqualified names default to "public" schema
  • Schema-qualified names preserved as-is
  • Same name in different schemas treated as distinct objects
  • Function identity includes argument types (overloads are distinct)
  • Built-in function in expression does NOT create dependency (e.g., now())
  • Built-in type in column does NOT create dependency (e.g., integer, text)
  • Reference to undeclared object is not a dependency (passes through to ProcessUtility for error)

Phase 2: Expression Dependency Extraction

2.1 Column DEFAULT and CHECK Expression Dependencies

  • DEFAULT nextval('my_seq') creates dependency on sequence
  • DEFAULT my_function() creates dependency on function
  • CHECK (validate_func(col)) creates dependency on function
  • CHECK with subquery referencing table creates dependency on table
  • DEFAULT with type cast to user type creates dependency on type
  • Multiple defaults referencing different functions resolved correctly
  • Column default with built-in function (e.g., now()) does NOT create dependency

2.2 View Query Dependencies

  • Simple SELECT FROM table creates dependency on table
  • JOIN across two tables creates dependencies on both
  • Subquery in WHERE referencing another table creates dependency
  • Function call in SELECT list creates dependency on function
  • CTE (WITH clause) — CTE name NOT treated as external dependency
  • CTE body referencing real table creates dependency on that table
  • Nested subquery in FROM (subselect) dependencies extracted
  • View referencing another view — dependency resolved
  • UNION/INTERSECT/EXCEPT across tables — all dependencies extracted
  • View with type cast to user type creates dependency

2.3 Index, Trigger, and Policy Expression Dependencies

  • Expression index with function call creates dependency on function
  • Partial index WHERE clause with function creates dependency
  • Trigger WHEN clause with function creates dependency
  • Policy USING expression with function creates dependency
  • Policy WITH CHECK expression with function creates dependency
  • Domain CHECK constraint with function creates dependency
  • Trigger EXECUTE FUNCTION reference creates dependency on function
  • Policy on table creates structural dependency on table
  • ALTER SEQUENCE OWNED BY creates dependency on target table

2.4 Function and Type Dependencies

  • Function parameter type referencing user type creates dependency
  • Function RETURNS user_type creates dependency on type
  • Function RETURNS SETOF table creates dependency on table
  • Function parameter DEFAULT expression with function creates dependency
  • Composite type column referencing another user type creates dependency
  • Range type with user-defined subtype creates dependency
  • Domain based on another domain creates dependency

Phase 3: Topological Sort, Cycles, and Complex Scenarios

3.1 Priority Layer Ordering

  • Schemas created before tables that reference them
  • Extensions created before types/functions they provide
  • Types created before tables using them as column types
  • Sequences created before tables with DEFAULT nextval referencing them
  • Tables created before views referencing them
  • Functions created before triggers referencing them
  • Tables created before indexes on them
  • FK constraints applied after all tables created
  • Comments applied after their target objects created
  • Grants applied after their target objects created

3.2 Topological Sort Within Layers

  • View A depends on View B — View B created first
  • Chain of 5 views (v5→v4→v3→v2→v1) — all created in correct order
  • Two independent views created without error (no false dependency)
  • Table with INHERITS parent — parent created first
  • Table PARTITION OF parent — parent created first
  • Composite type A references composite type B — B created first

3.3 Cycle Detection and Repair

  • Mutual FK between two tables — both created, FKs applied after (via FK layer)
  • Three-way FK cycle (A→B→C→A) — all tables created, FKs deferred
  • Self-referencing FK (table references itself) — handled correctly
  • Composite type mutual reference via arrays — shell types resolve the cycle
  • Unresolvable cycle produces clear error message

3.4 Complex Multi-Object SDL

  • Full schema with 10+ object types loaded from shuffled SDL
  • Schema with function used in CHECK, view, and trigger — single function resolved for all
  • Table with SERIAL column — implicit sequence created without explicit CREATE SEQUENCE
  • Materialized view with indexes — matview created before its indexes
  • Multiple schemas with cross-schema references
  • SDL producing identical catalog to LoadSQL with same DDL in correct order