Skip to content

Semantic layer relations#358

Merged
remi-td merged 3 commits into
mainfrom
semantic-layer-relations
Jun 30, 2026
Merged

Semantic layer relations#358
remi-td merged 3 commits into
mainfrom
semantic-layer-relations

Conversation

@remi-td

@remi-td remi-td commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Objective update the Teradata MCP Server Community Edition Semantic Layer to support relations and conditional join expansion while preserving the lightness of the current MCP Solution.

This gives us a MCP-first semantic layer definition: declared in a config file, exposed as a set of MCP tools and resources, and accessible to any agentic framework regardless of the degree of integration with Teradata.

In this release:
1. We stick to the "Cube" concept as a container for the relations/measures/dimensions.
2. Update the sql meaning so it represents either a database table/view or a query
3. add joins that describe joined objects (table/views/queries)
4. dimensions and measures refer to the objects defined in the main source (name) or joins ( joins.name)
5. Joins are only materialised if needed by a dimension/measure, or if optional: false. optional is an optional parameter and its default for is true
6. All common SQL join types are available
7. Parameters are defined at the cube level and can be referenced in any sql (if they are used against a joined object, then this join is materialised). Parameters may be optional (in that case and if present in the compiled SQL, they are valued NULL) or have a default value (in that case they are optional but always supplied with the default value to the compiler. That may result in the join referencing it to be always materialised).
8. Example of YAML description:

cubes:
  - name: orders
    sql: analytics.fact_orders # This can be a database object or a query (if query, then compiled as a sub-query/CTE)
    joins:
      - name: customers
        sql: select * from analytics.customers where customer_segment_cd = :customer_segment # This can be a database object or a query (if query, then compiled as a sub-query/CTE)
        on: "orders.customer_id = customers.customer_id"
        type: "inner"             # inner|left|right|cross 
      - name: products   # This join is only used as a filter if the product segment is specified in the input parameters
        sql: master_db.products # This can be a database object or a query (if query, then compiled as a sub-query/CTE)
        on: "orders.product_id = products.product_id and (products.product_segment_cd=:product_segment"
        type: "inner"             # inner|left|right|cross 
        optional: true            # only materialize join if a customers dimension is requested        
    dimensions:
      - name: order_date
        sql: order_date
        type: time
      - name: customer_region     # from the joined table
        sql: "customers.region"
        type: string
    measures:
      - name: total_revenue
        sql: "SUM(order_total)"
        type: number
    parameters:
        customer_segment:
            description: "The customer segment code ('BUSINESS', 'RETAIL') for the customer."        
            default:'RETAIL'
        product_segment:
            description: "The product segment to filter ('BUSINESS', 'RETAIL'). All product segments considered if not specified."        
            optional: True 

@remi-td remi-td merged commit d7289b3 into main Jun 30, 2026
5 checks passed
@remi-td remi-td deleted the semantic-layer-relations branch June 30, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant