@phase2 @acms @analyzer @postgresql_analyzer
Feature: PostgreSQLAnalyzer
  As a CleverAgents developer
  I want a PostgreSQL DDL analyzer that produces UKO triples from SQL files
  So that the ACMS can index database schemas into the UKO knowledge graph

  Scenario: Analyze CREATE TABLE
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE users (
          id SERIAL,
          name VARCHAR(100)
      );
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:Table"
    And the triples should include predicate "rdf:type" with object_uri "uko-data:Column"
    And the triples should include predicate "uko-data:dataType"

  Scenario: Analyze table with NOT NULL and PRIMARY KEY
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE accounts (
          id SERIAL PRIMARY KEY,
          email VARCHAR(255) NOT NULL
      );
      """
    Then the triples should include predicate "uko-data:isPrimaryKey" with object_value "true"
    And the triples should include predicate "uko-data:isNullable" with object_value "false"

  Scenario: Analyze FOREIGN KEY
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE orders (
          id SERIAL PRIMARY KEY,
          user_id INTEGER NOT NULL,
          FOREIGN KEY (user_id) REFERENCES users(id)
      );
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:ForeignKey"
    And the triples should include predicate "uko-data:foreignKeyTo"

  Scenario: Analyze CREATE VIEW
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE VIEW active_users AS
      SELECT * FROM users WHERE active = true;
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:View"
    And the triples should include predicate "rdfs:label" with object_value "active_users"

  Scenario: Analyze CREATE SCHEMA
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE SCHEMA IF NOT EXISTS app;
      CREATE TABLE app.users (
          id SERIAL PRIMARY KEY
      );
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:Schema"
    And the triples should include predicate "rdfs:label" with object_value "app"
    And the triples should include predicate "uko:contains" linking subject "schema" to object "users"

  Scenario: Analyze schema-qualified table includes schema in column URIs
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE myschema.items (
          id SERIAL PRIMARY KEY,
          name VARCHAR(100)
      );
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:Table"
    And the triples should include predicate "rdf:type" with object_uri "uko-data:Column"
    And the triples should include predicate "uko:contains" linking subject "myschema" to object "items"

  Scenario: Analyze table with composite PRIMARY KEY
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE user_roles (
          user_id INTEGER NOT NULL,
          role_id INTEGER NOT NULL,
          PRIMARY KEY (user_id, role_id)
      );
      """
    Then the triples should include predicate "uko-data:isPrimaryKey" with object_value "true"

  Scenario: Analyze empty SQL content raises ValueError
    Given a PostgreSQLAnalyzer analyzer
    Then analyzing empty content with this analyzer should raise ValueError

  Scenario: Analyze whitespace-only SQL content raises ValueError
    Given a PostgreSQLAnalyzer analyzer
    Then analyzing whitespace-only content with this analyzer should raise ValueError

  Scenario: Analyze SQL with empty resource_uri raises ValueError
    Given a PostgreSQLAnalyzer analyzer
    Then analyzing content with empty resource_uri should raise ValueError

  Scenario: Analyze SQL with comments does not produce phantom triples
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      -- CREATE TABLE phantom (id INT);
      /* CREATE VIEW ghost AS SELECT 1; */
      CREATE TABLE real_table (id SERIAL PRIMARY KEY);
      """
    Then the triples should include predicate "rdfs:label" with object_value "real_table"
    And the triples should not include predicate "rdfs:label" with object_value "phantom"
    And the triples should not include predicate "rdfs:label" with object_value "ghost"

  Scenario: Analyze multi-column FOREIGN KEY
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE user_roles (
          user_id INTEGER NOT NULL,
          role_id INTEGER NOT NULL,
          PRIMARY KEY (user_id, role_id),
          FOREIGN KEY (user_id, role_id) REFERENCES lookup(uid, rid)
      );
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:ForeignKey"
    And the triples should include predicate "uko-data:foreignKeyTo" with object_uri containing "uid"
    And the triples should include predicate "uko-data:foreignKeyTo" with object_uri containing "rid"

  Scenario: Analyze CREATE VIEW captures viewDefinition
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE VIEW active_users AS
      SELECT id, name FROM users WHERE active = true;
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:View"
    And the triples should include predicate "uko-data:viewDefinition"

  Scenario: Duplicate CREATE TABLE is deduplicated
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE items (id SERIAL);
      CREATE TABLE items (id SERIAL, name TEXT);
      """
    Then the triples should include predicate "rdf:type" with object_uri "uko-data:Table"
    And the number of Table type triples should be 1

  Scenario: Analyze invalid SQL returns empty list
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      THIS IS NOT VALID SQL AT ALL;
      JUST RANDOM TEXT HERE;
      """
    Then no triples should be returned

  # -- Regression tests for F3 (string-literal parentheses) --

  Scenario: DEFAULT with parentheses in string literal does not truncate columns
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE config (
          col1 TEXT DEFAULT 'hello(world)',
          col2 INTEGER
      );
      """
    Then the triples should include predicate "rdfs:label" with object_value "col1"
    And the triples should include predicate "rdfs:label" with object_value "col2"

  Scenario: CHECK constraint with string containing parentheses
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE validated (
          status TEXT CHECK (status IN ('active(1)', 'inactive(0)')),
          amount INTEGER
      );
      """
    Then the triples should include predicate "rdfs:label" with object_value "status"
    And the triples should include predicate "rdfs:label" with object_value "amount"

  # -- Regression test for F6 (quoted keyword column names) --

  Scenario: Quoted keyword column names are not silently dropped
    Given a PostgreSQLAnalyzer analyzer
    When I analyze the SQL content:
      """
      CREATE TABLE reserved_words (
          "primary" INTEGER,
          "check" VARCHAR(50),
          normal_col TEXT
      );
      """
    Then the triples should include predicate "rdfs:label" with object_value "primary"
    And the triples should include predicate "rdfs:label" with object_value "check"
    And the triples should include predicate "rdfs:label" with object_value "normal_col"
