TQL Language Features

TQL requires a new set of features for insert-select queries:

  • Unbound parameters should be allowed in the select clause of these queries, permitting the insertion of new blank nodes.
  • The select clause should permit a multiple of 3 items, and not just the current 3 items, permitting multiple insertions for each row of the returned result.

    The second of these features is the more difficult, as it needs to intercept the code path which is performing insertions of raw data into the indexes. It could be done either by mapping each insertion into a set of triples to be inserted, or else the insertions could be repeated, with a different set each time.

    The purpose of these features is to allow for queries like the following:

    insert select
        $item <ns:length> $blank
        $blank <ns:units> <ns:inches>
        $blank <ns:value> $length
      from <rmi://localhost/server1#model>
      where $item <ns2:inchLengh> $length
    into <rmi://localhost/server1#model>;
    

    This query cannot be performed as a set of 3 separate insertions, as it requires the same blank node in each statement. The only option at the moment is to build up the insertions manually from the client end, but this has several problems:

  • Will require a new insertion for every record returned from the select clause.
  • Must be performed on a client, and not done in the server.
  • Cannot be included as a part of the rules engine.

The problem in the rules engine is the most important, as this type of statement is required to perform rules on n-ary predicates. The rules themselves never use iTQL to be parsed, but the equivalent query objects are still constructed.

As an example, the following rule:

element(ID, X1, Y1, X2, Y2) :- linguistic_element(ID, X1, Y1, X2, Y2).

Will be mapped to:
insert
  select
    $id <pred:element> $a
    $a <e:1> $x1
    $a <e:2> $y1
    $a <e:3> $x2
    $a <e:4> $y2
  from <rmi://localhost/server1#model>
  where
    $id <pred:linguistic_element> $b and
    $b <e:1> $x1 and
    $b <e:2> $y1 and
    $b <e:3> $x2 and
    $b <e:4> $y2
into <rmi://localhost/server1#model>;

original page by Paul Gearon on Nov 01, 2006

----
Select clauses are tested for a width of 3 at:

resolver/java/org/mulgara/resolver/ModifyModelOperation.java:164

----
The width is tested again at line:

resolver/java/org/mulgara/resolver/ModifyModelOperation.java : 204

The statements to be inserted are instantiated at line 205:

1   statements = new [[TuplesWrapperStatements]](
2       new [[LocalizedTuples]](systemResolver, answer),
3       varsr0, varsr1, varsr2);

It may be possible to wrap this in a loop, with the vars offsets added to an incrementing loop variable. The trick here is identifying unbound vars and ensuring that they are replaced with a new blank node.

----
The 2 parameter LocalizedTuples constructor presumes a non-persistent localization. This is incorrect for blank nodes. So if the answer object contains an unbound variable, then the different constructor should be used.

However, if the loop around the TuplesWrapperStatements constructor is to be followed, then blank nodes will need to be stored from one instance to the next. This is possible, but would require storage of the complete list, which may be larger than memory.

The other option is to create a new Tuples Wrapper which is aware of the N*3 columns, and shifts sideways with each call to next(). This can then allocate new blank nodes during iteration, and drop them every Nth call to next().