logo       


A suggestion for TMQL: msg#00000

Subject: A suggestion for TMQL
Dear all,

Please find attached a very early draft of a suggestion for TMQL. It is
presented as a "quasi-tutorial" because it is very far from being a
solid vision. 

The language is based very much on ideas from AsTMa* and Tolog, and also
from SQL and from the usual object oriented notation.

I will appreciate any feedback.

Thanks 

Rani
-- 
Rani Pinchuk
Software Engineer
Space Applications Services
Leuvensesteenweg, 325
B-1932 Zaventem
Belgium

Tel.: + 32 2 721 54 84
Fax.: + 32 2 721 54 44

http://www.spaceapplications.com 

Attachment: style.css
Description: Text Data


Quasi-Tutorial for a Suggested TMQL

Introduction

Because the language that is shown below is very young, I chose to present it as a quasi-tutorial. It contains many examples but also some definition parts. However it is very far from being a language specification.

I was hoping to uncover some difficulties in the language itself, but also to generate a somewhat readable document that exposes what I believe to be the strengths of the language.

It is my hope that this document will bring much feedback (hopefully constructive :-), so the language can be developed to a more consistent and powerful language.

The language below is strongly based on two other languages for dealing with topic maps, tolog (of Ontopia) and AsTMa* (of Robert Barta), and on SQL. I even used some examples from the presentation of tolog and the tutorials of AsTMa*. Actually I see this effort as an integration effort among the ideas I took from those languages.

When doing this pre-designing of the language (if it might be called that way) I had in mind two targets:

Power
The language suppose to let the user to query most if not all the queries he/she might have in mind.

Simplicity
In order for a new language to become popular, it must be easy to learn and use.

Usually, the above two targets contradict each other. However, they guided me in making the following decisions:

  1. Basing the syntax as much as possible on the well known SQL. This simplified the learning process of the language at least for those who know already SQL. SQL also deals with quite similar problems, so I found good match between its structure and the needs.

  2. No support for generating a presentation of the results in different formats. Like SQL, it seems that this language will be embedded within other more generic languages (Perl, Java, C etc). On the other hand the number of formats and presentations that might be needed is uncountable. Usually the host languages are already capable of providing with formating/presentation means. Therefore I thought that the loss of moving the formatting/presentation part out of the language to the host language makes sense.

    In this context see also the Skin design pattern.

    In the context of embedding the language in other language, see the Phrasebook design pattern.

  3. Treating topics as objects. As was said before, ``everything in a topic map is a topic''. And a topic is a structure that holds various data and references to data. Therefore it made sense to treat it as an object. This implied the usage of accessors - in order to access the elements of the object. I found that AsTMa= provides very clear symbols that actually play as accessors (such as the scope character @). The accessors found to be (in my humble opinion) a good thing, as they let us ``navigate'' within the topic object and also to other topic objects. Although the accessors might seem confusing at first, they provide huge power in reasonable complexity.

Finally, I am well aware that the description below does not include all the facilities that the language suppose to include. In many places I assume knowledge of SQL by the reader. For example, I did not include any built-in functions like the functions provided by SQL. I also did not include macros or function definitions. I guess that if the development of this language goes on, there should be a careful process of choosing what of those functions and other facilities should be adopted in the language.

Selection by Topics

We start with the most simple case - selecting a certain topic from a certain topic map:

  select $person from tm://my/topic/map where $person.id = 'Jonathan';

We can see that we select from a certain topic map that is defined by the from clause. Instead of doing that, we could choose to work from now on with that topic map:

  use tm://my/topic/map;
  select $person where $person.id = 'Jonathan';

We treat topics as objects that have id, base name etc. Dollar followed by any alphanumeric character, underscore or hyphen is a variable that can hold a topic object.

Topic Accessors

We can access the topic elements as follows:

id
.id will give us the topic id:
  $person.id

base name
.bn will give us the topic base name:
  $person.bn

The @ character will let us alter the scope. So for example

  $city.bn@en

will give us the base name of the city in the English scope.

type
A topic type (is-a relationship) is a topic by itself. We use the .type() where inside the brackets we can place a number, or an asterisk.

The following refers to the type of $person topic:

  $person.type(0)

We can refer to the type of the superclass of $person topic like this:

  $person.type(1)

If we want to refer to the type of $person or the type of any superclass of it, we can write:

  $person.type(*)

We can also use the .. operator as follows:

  $person.type(0..1)

The above refers to the type of $person and to the type of its type.

Note that because .type() returns a topic, we can use o it any of the other accessors. For example, the following is the base name of the type of $person:


  $person.type(0).bn

occurrence
Occurrence can be a reference or in-line. We can refer to occurrence by three accessors: .oc, .ref or .in. .oc refers to any occurrence no matter if it is a reference or in-line. .ref refers only to references and .in refers only to in-lines.

Each occurrence might have a scope and a type. We refer to the scope by using again the character @. We refer to the type by placing it inside brackets just after the accessor. If we want to refer both to the scope and to the type, we place always the brackets in the end.

Example:

  $person.in
  $person.ref@en(cv)
  $person.oc@en(birthdate)

Note that the occurrence accessors return the data itself (so the reference or the in-line). However, if another accessor is placed after those accessors it will refer to the topic of the type of the occurrence. So the following:

  $person.in(cv).bn

might give us ``Curriculum Vitae'' which is the base name of the topic with id 'cv'.

role
The accessors .role() implies that the element before them is an association.
   $a.role('location')

implies that $a is an association that has a role which its id is 'location'. By writing the above we refer to the topic that plays that role (so the topic that plays the role 'location').

Thus,

   $a.role('location').bn

refers to the base name of the topic which plays the 'location' role.

In the same way,

   $a.role(*)

implies that $a is an association that has whatever role and we refer to the topic that plays that whatever role.

If we put a variable inside the brackets, we get the actual topic that describe the role. So

   $a.role($b)

is very similar to last example, but $b will be populated with the topic object that describes that role. Later we will see how we use this structure in order to restrict the roles of an yet unknown association, or to find what are the roles of certain association.

Simple Topic Selects

  • Select a topic by its base name:
        select $city where $city.bn@fr = 'Anvers'

  • Select a topic by its type base name
        select $language where $lanaguge.type(0).bn = 'Object Oriented Language';
        select $language where $language.type(0..1).bn = 'Computer Language';
        select $language where $language.type(*).bn = 'Computer Language';

  • Select a topic by its occurrence
        select $language where $language.ref = 'http://www.perl.com'

  • Select a topic that has occurrence in English and that the French base name of the type of that occurrence is 'ville'.

    Note that the moment we add an accessor after the .oc, .ref or or .in, we refer to the topic map of the type of the occurrence and not to the reference or the in-line data.

        select $city where $city.ref@xxxxx@fr = 'ville'

  • Select a topic by the base name of its occurrence type
        select $c where $c.oc.bn = 'City'

  • Select a topic by its in-line occurrence.
        select $a where $a.in@en(city) =~ 'Antwerp';

    Here we select the in-line data that match the simple string 'Antwerp'. In general, the language supports regular expressions style Perl5. It is done by using the operators =~ or !~ followed by the regular _expression_. The first non white character after the operator will be the delimiter of the regular _expression_. So the above could be written also like:

        select $a where $a.in@en(city) =~ /Antwerp/;

    or:

        select $a where $a.in@en(city) =~ sAntwerps;

The Returned Values

In the examples above, we list only the actual topic objects as the returned values. We can deal with those objects with whatever programming interface we use.

However, we can also request only certain data out of the returned value, again using the accessors. Examples:

  • Select the id of the topic:
      select $bla.id ...

  • Select the base name of the topic:
      select $bla.bn ...

  • Select the type of the topic (so select the superclass topic):
      select $bla.type(0) ...

  • Select the base name of the type of the topic:
      select $bla.type(0).bn ...

  • Select certain occurrence of the topic:
      select $person.ref@en(homepage) ...

    It is not yet decided what happens if there is more then one occurrence that can be returned (in the example above - two or more homepages in English). One possibility is to return one of them. Other possibility is to return always an array, when occurrences is requested. Yet another possibility is to forbid to request an occurrence all together - and to demand that the occurrences will be retrieved via the topic object.

Selection by Associations

When we select by an association, we know the actual association, and can refer to it by its id.

Let us examine an example. Select a person that was born in a city that is called in Dutch 'Antwerpen':

    select $person where born_in.person = $person 
                     and born_in.location.bn@nl = 'Antwerpen'

We can see that we use kind of accessors (role names) for an element that is not a variable. 'born_in' in the example above, is the id of an association. Any id of association followed by a dot and a role name refers to the topic that plays that role in that association.

Because the structure <association_id>.<role_name> refers to a topic, we can use the usual accessors on that topic.

We can also see that we use and between two parts of the where clause. We can use and and or and group them using brackets as it is done in SQL.

Sometimes though we will need to refer to the same association more then once in the same where clause. We can do that by using the aliases clause. For example, the following query selects a part that is contained in other part that is contained in a spaceship.

    select $part
       aliases contains contains1, contains contains2
        where contains1.part = $part 
          and contains1.whole = contains2.part
          and contains2.whole.id = 'spaceship';

We can also use the negation operator not or use the != operator. In the following example we get all the employees that are not managers of the same company where they are employed:

  select $person, $company
     where (managed_by.manager != $person 
            and managed_by.company = $company)
       or  (employed_by.company = $company 
            and employed_by.employee = $person);

This can be written also as:

  select $person, $company
     where not (managed_by.manager != $person
                and managed_by.company = $company)
           or  (employed_by.company = $company 
                and employed_by.employee = $person);

Note that not always we need to mention all the association roles in a query. Consider the following example which query who manages whatever company:

  select $person where managed_by.manager = $person;

Sometimes we might want to know how two or more topics might be associated. We can do that by using the .role() accessor.

The following query selects an association that connects two topics - one with base name 'Antwerpen' and the other with base name 'Jonathan' (will return the association topic 'born_in').

Note that the usage of the accessor .role() implies that the element before it is an association. And remember also that when using .role() we look at the topic that plays that role.

    select $a where $a.role(*).bn@nl = 'Antwerpen'
                and $a.role(*).bn = 'Jonathan';

As we saw above, we can check what are the roles we found by placing a variable in the brackets of .role():

    select $a, $r1, $r2 where $a.role($r1).bn@nl = 'Antwerpen'
                          and $a.role($r2).bn = 'Jonathan';

In a similar way, we can restrict the roles we found:

    select $a where $a.role($r).bn@nl = 'New York'
                and $a.role(*).bn = 'Roni'
                and $r != 'state';

We can also use scope over an association. We do that by using the @... accessor over the object that represents the association. For example, if Jonathan is now in Antwerpen, he might have the association located_in. Yet, that association will not be active under the 'history' scope, and only born_in association will be returned:

    select $a where $a@xxxxxxxxxxxx(*).bn@nl = 'Antwerpen'
                and $a@xxxxxxxxxxxx(*).bn = 'Jonathan'

Note that we could write the above also like this:

    select $a where $a@xxxxxxxxxxxx(*).bn@nl = 'Antwerpen'
                and $a.role(*).bn = 'Jonathan'

The moment a topic object got a scope, it will be kept. The following on the other hand is an error:

    select $a where $a@xxxxxxxxxxxx(*).bn@nl = 'Antwerpen'
                and $a@xxxxxxxxxxxx(*).bn = 'Jonathan'    # an error !!

The last examples bring us to the domain of introspective queries that will be discussed next.

Learning the Structure of the Topic Map

Get all the topics:

    select $a where exists $a;

We use the exists keyword that returns true if the _expression_ that follows it exists in the topic map.

Get all the associations:

    select $a where exists $a.role(*);

Select all association types in this topic map:

    select distinct $a.type(0) where exists $a.role(*);

Note that we use the distinct keyword. This keyword make sure that each row of the result set is unique.

Select an association that has a role named 'location' or 'placed':

    select $a where exists $a.role('location') 
                 or exists $a.role('placed')

Select all role types used in more than one association type:

    select distinct $a where exists $a.role($r)
                         and exists $b.role($r)
                         and $a != $b;

Select all occurrence types:


    select distinct $a where $b.oc.type(0) = $a;

In order to query about scopes we first examine the scope character @. Because a scope can be seen also as a topic, the string we place after the @ character is the id of the topic that represents the scope. However, we can also place a variable after the scope character. for example:

  $city.bn@$language

However, we should be careful with precedence issues. For example, in

  $a@$scope.role(*).bn@nl

it is not clear if

  .role(*).bn@nl

is referring to $scope or to

  $a@$scope

Actually, all the accessors refer to the immediate element from their left. So probably we want to write the above as:

  ($a@$scope).role(*).bn@nl

Using a variable after the scope character, we can select all scopes:

    select distinct $s where exists $t@$s
                          or exists $t.oc@$s
                          or exists $t.bn@$s;

We can also select the scope of certain occurrence. For example checking in which languages (so scopes, in that case) the CV of certain person is available.

    select $s where $person.id = 'michael' 
                and exists $person.oc@$s('cv');

Sorting the Results

The results from the query are returned as rows of topic objects or strings. We can sort the results by using the order by keyword. When we order by a topic object, its id will be taken for determining the order. So:

   ... order by $t

and

   ... order by $t.id

is actually the same.

We can order by several variables, and we can reverse the order with the keyword 'desc':

   ... order by $a, $b.bn@en decs, $c.type(0).bn;

Author & Copyright

Rani Pinchuk, <rp@xxxxxxxxxxxxxxxxxxxxx>

Copyright (c) 2003 Space Applications Services

Ruby Jobs
Java Jobs
Jobs in California
more...
what
job title, keywords
where
city, state, zip
jobs by job search
Search:
Java, servers, webhosting, windows, cisco ...
more...
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
encryption.gpg....    ietf.rfc822/199...    freebsd.devel.i...    lang.haskell.li...    mail.squirrelma...    web.zope.plone....    yellowdog.gener...    text.xml.xalan....    recreation.phot...    kde.devel.educa...    hardware.bus.ca...    printing.ghosts...    voip.peering/20...    assembly/2006-0...    org.user-groups...    culture.interne...    network.i2p/200...    boot-loaders.ya...    xfree86.render/...    qnx.openqnx.dev...    jakarta.velocit...    user-groups.pal...   
Home | blog view | USPTO Patent Archive | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe