16.5.6.Describing Source Relational Tables

Quad map patterns of an application usually share a common set of source tables and quad map values of one pattern usually share either a single table or very small number of joined tables. Join and filtering conditions are also usually repeated in different patterns. It is not necessary to type table descriptions multiple times, they are declare once in the beginning of storage declaration statement and shared between all quad map declarations inside the statement. Names of aliases can be used instead of table names in quad map values.

FROM DB.DBA.SYS_USERS as user WHERE (^{user.}^.U_IS_ROLE = 0)
FROM DB.DBA.SYS_USERS as group WHERE (^{group.}^.U_IS_ROLE = 1)
FROM DB.DBA.SYS_USERS as account
FROM user as active_user
  WHERE (^{active_user.}^.U_ACCOUNT_DISABLED = 0)
FROM DB.DBA.SYS_ROLE_GRANTS as grant
  WHERE (^{grant.}^.GI_SUPER = ^{account.}^.U_ID)
  WHERE (^{grant.}^.GI_SUB = ^{group.}^.U_ID)
  WHERE (^{grant.}^.GI_SUPER = ^{user.}^.U_ID)

This declares five distinct aliases for two distinct tables, and six filtering conditions. Every condition is an SQL expression with placeholders where a reference to the table should be printed. The SPARQL compiler will not try to parse texts of these expressions (except dummy search for placeholders), so any logical expressions are acceptable. When a quad map pattern declaration refers to some aliases, the WHERE clause of the generated SQL code will contain a conjunction of all distinct texts of "relevant" conditions. A condition is relevant if every alias inside the condition is used in some quad map value of the map pattern, either directly or via clause like from user as active_user . (user is a "base alias " for active_user ).

Consider a group of four declarations.

graph <http://myhost/sys>
  {
    oplsioc:user_iri (active_user.U_ID)
        a oplsioc:active-user .
    oplsioc:membership_iri (grant.GI_SUPER, grant.GI_SUB).
        oplsioc:is_direct
            grant.GI_DIRECT ;
        oplsioc:member-e-mail
            active_user.U_E_MAIL
               where (^{active_user.}^.U_E_MAIL like 'mailto:%').
    ldap:account-ref (account.U_NAME)
        ldap:belongs-to
            ldap:account-ref (group.U_NAME) option (using grant).
  }

The first declaration will extend <http://myhost/sys> graph with one imaginary triples { user a oplsioc:active-user } for every account record that is not a role and not disabled. The second declaration deals with membership records. A membership is a pair of a grantee ("super") and a granted role ("sub") stored as a row in DB.DBA.SYS_ROLE_GRANTS ).

The second declaration states that every membership has oplsioc:is_direct property with value from GI_DIRECT column of that table (roles may be granted to other roles and users, so permissions are "direct" or "recursive").

The third declaration declares oplsioc:member-e-mail property of memberships. The value is a literal string from DB.DBA.SYS_USERS.U_E_MAIL , if the grantee is active (not disabled) and is not a role and its e-mail address starts with 'mailto:' . The join between DB.DBA.SYS_ROLE_GRANTS and DB.DBA.SYS_USERS is made by equality (GI_SUPER = U_ID) because the alias active_user in the declaration "inherits" all conditions specified for user . In addition, the SPARQL compiler will add one more condition to check if the U_E_MAIL is not null because the NULL value is not a valid object and it knows that U_E_MAIL is not declared as NOT NULL .

The last declaration contains an option clause. As usual, this indicates that the basic functionality is good for many tasks but not for all. In this declaration, the ldap:belongs-to property establishes a relation between grantee (subject) and a granted role (object). Both subject and object IRIs are based on account name, DB.DBA.SYS_USERS.U_NAME , so the quad map pattern contains two references to different aliases of DB.DBA.SYS_USERS but no alias for DB.DBA.SYS_ROLE_GRANTS . Hence the declaration could produce a triple for every row of the Cartesian product of the DB.DBA.SYS_USERS . To fix the problem, option (using alias-name) tells the compiler to process the alias-name as if it's used in some quad map value of the pattern.

It is an error to use an alias only in where clause of the quad map pattern but neither in values or in option (using alias-name) . To detect more typos, an alias used in quad map values can not appear in option (using alias-name) clause.