A novel system, computer readable storage medium and method for creating re-usable queries over complex data including hierarchies, trees and graphs is described. This is achieved by an object-oriented query language, where a class is a logical property of a data item, and inheritance is implication between such properties. Virtual method calls execute all relevant method implementations in most specific classes. Expressions can be multi-valued, thus avoiding the need for naming intermediate results. All constructs closely follow the syntax of mainstream object-oriented languages like Java.
|
1. A process for creating re-usable queries over complex data, the process comprising:
defining a re-usable object-oriented receiving queries defined in a first query language with in which logical properties are represented by object-oriented classes treated as logical properties, wherein each logical property is defined by one or more specified classes of at least one complex data item and in which inheritance relationships between the classes represent relationships between the logical properties, and wherein the queries include requests for data items having requested logical properties;
relating inheritance, used to form new class with the specified classes, to the logical properties along with a plurality of virtual method calls that execute all applicable method implementations in at least one of the specified classes; and
in response to the queries requesting data items having logical properties encoded as methods of particular classes, dispatching on the logical properties particular classes to choose at least one one or more most specific implementation implementations of an operation the methods, wherein a most specific implementation of a method is in a class where no subclasses define a same method other classes that inherit from the class include an implementation of the method, wherein the dispatching on the logical properties particular classes further includes:
defining identifying a named predicate p as predicate p(T1x1, . . . , Tnxn) {formula} for each one of the applicable method most specific implementations, wherein the named predicate p has variables x1, . . . , xn. so as to restrict a range of a relation, which contains tuples (x1, . . . xn) where each xi has a type T Ti;
testing a receiver against each relevant type and choosing the applicable method implementations from the most specific implementations, wherein testing a type of the receiver is achieved by includes invoking a named constructor for each class defining a method of a relevant signature most specific implementation, regardless of static types;
implementing queries by translating actual or possibly recursive object-oriented the queries to a second query language using for each method and constructor of each class, a first special variable that holds a value that is a member of the class, and for each method that is not a predicate, a second special variable that holds a result of a method; and
rending rendering the queries concise by at least using multi-valued operations to avoid naming intermediate results in nested method calls.
11. A computer program product for creating re-usable queries over complex data, the computer program product comprising:
a non-transitory computer readable storage medium, the non-transitory computer readable storage medium storing software programming instructions capable of performing with a processor programming code to carry out:
defining a re-usable object-oriented receiving queries defined in a first query language with in which logical properties are represented by object-oriented classes treated as logical properties, wherein each logical property is defined by one or more specified classes of at least one complex data item and in which inheritance relationships between the classes represent relationships between the logical properties, and wherein the queries include requests for data items having requested logical properties;
relating inheritance, used to form new class with the specified classes, to the logical properties along with a plurality of virtual method calls that execute all applicable method implementations in at least one of the specified classes; and
in response to the queries requesting data items having logical properties encoded as methods of particular classes, dispatching on the logical properties particular classes to choose at least one one or more most specific implementation implementations of an operation the methods, wherein a most specific implementation of a method is in a class where no subclasses define a same method other classes that inherit from the class include an implementation of the method, wherein the dispatching on the logical properties particular classes further includes:
defining identifying a named predicate p as predicate p(T1x1, . . . , Tnxn) {formula} for each one of the applicable method most specific implementations, wherein the named predicate p has variables x1, . . . , xn so as to restrict a range of a relation, which contains tuples (x1, . . . , xn) where each xi has a type Ti;
testing a receiver against each relevant type and choosing the applicable method implementations from the most specific implementations, wherein testing a type of the receiver is achieved by includes invoking a named constructor for each class defining a method of a relevant signature most specific implementation, regardless of static types;
implementing queries by translating actual or possibly recursive object-oriented the queries to a second query language using for each method and constructor of each class, a first special variable that holds a value that is a member of the class, and for each method that is not a predicate, a second special variable that holds a result of a method; and
rending rendering the queries concise by at least using multi-valued operations to avoid naming intermediate results in nested method calls.
16. An information processing system for creating re-usable queries over complex data, the system comprising:
a computer memory capable of storing machine instructions; and
a processor in communication with said computer memory, said processor configured to access the memory, the processor performing
a re-usable object-oriented query language defined with object-oriented classes treated as logical properties, wherein each logical property is defined by one or more specified classes of at least one complex data item;
a new class formed by relating inheritance with the specified classes, to the logical properties along with a plurality of virtual method calls that execute all applicable method implementations in at least one of the specified classes; and and execute the machine instructions to perform operations comprising:
receiving queries defined in a first query language in which logical properties are represented by object-oriented classes, and in which inheritance relationships between the classes represent relationships between the logical properties, and wherein the queries include requests for data items having requested logical properties;
means for in response to the queries requesting data items having logical properties encoded as methods of particular classes, dispatching on the logical properties particular classes to choose at least one or more of a most specific implementation implementations of an operation the methods, wherein a most specific implementation of a method is in class where no subclasses define a same method other classes that inherit from the class include an implementation of the method, wherein the dispatching on the logical properties particular classes further includes:
means for defining identifying a named predicate p as predicate p(T1x1, . . . Tnxn) {formula} for each one of the applicable method most specific implementations, wherein the named predicate p has variables x1, . . . xn. so as to restrict a range of a relation, which contains tuples (x1, . . . , xn) where each x1 has a type Ti;
means for testing a receiver against each relevant type and choosing the applicable method implementations from the most specific implementations, wherein testing a type of the receiver is achieved by includes invoking a named constructor for each class defining a method of a relevant signature most specific implementation, regardless of static types;
means for implementing queries by translating actual or possibly recursive object-oriented the queries to a second query language using for each method and constructor of each class, a first special variable that holds a value that is a member of the class, and for each method that is not a predicate, a second special variable that holds a result of a method; and
means for rending rendering the queries concise by at least using multi-valued operations to avoid naming intermediate results in nested method calls.
2. The process as set forth in
3. The process as set forth in claim 1 2, wherein translating the implementing queries includes mapping instanceof tests and cast expressions to calls of such each characteristic predicates.
4. The process as set forth in
5. The process as set forth in
6. The process as set forth in
using a * notation and a + notation on multi-valued operations to indicate a chained application of such operations; and or
using an aggregate notation with variables, a range condition and an expression (agg(vars|condition|expr)).
7. The process as set forth in
8. The process as set forth in
a data item in a hierarchy;
a tree; and or
a graph.
9. The process as set forth in
a textual form;
a graphical form;
a query-by-example user interface form; and or an
embedded in a more general form within another programming language.
10. The process as set forth in claim 1 7, wherein complex data is stored in a plurality of datasource formats including the data storage includes at least one of:
a relational database;
a web service;
a web page; and or
a structured data file on hard disk and column types are used to build a hierarchy of object-oriented classes on top of such data formats, by annotating each relevant data format schema.
12. The computer program product of
13. The computer program product of claim 11 12, wherein translating the implementing queries includes mapping instanceof tests and cast expressions to calls of such each characteristic predicates predicate.
14. The computer program product of
15. The computer program product of
17. The system of
18. The system of claim 16 17, wherein translating the implementing queries includes mapping instanceof tests and cast expressions to calls of such each characteristic predicates.
19. The system of
20. The system of
|
This application is
This defines a named predicate p with variables x1, . . . , xn. In a departure from classical Datalog each variable is given a type. These restrict the range of the relation, which only contains tuples (x1, . . . , xn) where each xi has the type Ti.
The body of a Datalog predicate is a logical formula over the variables defined in the head of the clause. These formulas can be built up as follows:
formula ::=
predicate(variable, . . . , variable)
| test(variable, . . . , variable)
| variable = expr
| not(formula)
| formula or formula
| formula and formula
| exists(Type variable | formula)
That is, a formula is built up from uses of predicates through the standard logical operations of negation, disjunction, conjunction and existential quantification. In addition to predicates, tests are allowed in Datalog programs. A test is distinct from a predicate in that it can only be used to test whether results are valid, not generate results. An example of a test is a regular expression match. The test matches(“C %”,X) is intended to match all strings beginning with “C”. Evidently such a test cannot be used to generate strings, as there are infinitely many possible results, but may constrain possible values for X. In contrast, a predicate such as employee(SSN,NAME) may generate values—in this case, the variables SSN and NAME are bound to each pair of elements for which person SSN has name NAME.
Arguments to predicates are simply variables in Datalog, but expressions allow the computation of arbitrary values. Expressions are introduced through formulas such as X=Y+1 defining the value of a variable, and include all arithmetic and string operators. In addition, expressions allow aggregates to be introduced:
expr ::= variable
| constant
| expr + expr
| expr * expr
| . . .
| aggregate
Our definition of Datalog differs from usual presentations of the language in several respects. The first difference is largely inessential. While we allow arbitrary use of logical operators in formulas, most presentations require Datalog predicates to be in disjunctive normal form, where disjunction can only appear at the top level of a predicate and the only negated formulas are individual predicates. However, any formula may be converted to disjunctive normal form, so this does not represent a major departure from pure Datalog. Expressions, on the other hand, are crucial in increasing the expressiveness of the language. In pure Datalog expressions are not allowed, and this extension to pure Datalog is non-trivial, with an impact on the semantics of the language.
Datalog Programs
A Datalog program contains three parts:
A query. This is just a Datalog predicate defining the relation that we wish to compute.
A set of user-defined, or intensional predicates. These predicates represent user-defined relations to be computed to evaluate the query.
A set of extensional predicates. These represent the elements stored in the database to be queried.
The general structure of a Datalog program therefore mirrors that of a .QL program. The query predicate corresponds to the query in a .QL program, while classes and methods may be translated to intensional predicates. Finally, in the context of program queries the extensional predicates define the information that it stored about the program. Examples were given in the sections above beginning with database annotations.
Semantics and Recursion
The semantics of Datalog program are very straightforward, in particular in comparison to other forms of logic programming such as Prolog. A key property is that termination of Datalog queries is not an issue. The simplicity of the semantics of Datalog programs (and by implication of .QL programs) is an important factor in its choice as an intermediate query language, as it is straightforward to generate Datalog code. It is worth exploring the semantics in a little more detail, however, as a few issues crop up when assigning meaning to arbitrary Datalog programs.
For our purposes, the meaning of a Datalog program is that each predicate defines a relation, or set of tuples, between its arguments. Other, more general, interpretations of Datalog programs are possible such as those described in Allen van Gelder and Kenneth A. Ross and John S. Schlipf. The Well-Founded Semantics For General Logic Programs. Journal of the ACM, volume 38, number 3, pages 620-650, 1991, the teachings of which are hereby incorporated by reference in its entirety. An important feature is that these relations should be finite, so that they may be represented explicitly in a database or in memory. It is customary to enforce this through range restriction, that is to say ensuring that each variable that is an argument to a predicate should be restricted to a finite set. In our case, this is largely straightforward, as each variable is typed. Column types such as @person or @department restrict variables to certain kinds of information already in the database, in this case the sets of classes or reference types in the program. As there can only be finitely many of these, any variable with such a type is automatically restricted. However, primitive types such as int are more troublesome. Indeed it is easy to write a predicate involving such variables that defines an infinite relation:
predicate p(int X,int Y){X=Y}
This predicate contains all pairs (X,X), where X is an integer, which is infinite and therefore disallowed. For that reason, the type system of—QL ensures that any variable of primitive type is always constrained by a predicate, restricting its range to a finite set.
In the absence of recursion, the semantics of a Datalog program is very straightforward. The program can be evaluated bottom-up, starting with the extensional predicates, and working up to the query. Each relation, necessarily finite by range-restriction, can be computed from the relations it depends on by simple logical operations, and so the results of the query can be found.
The situation is more interesting in the presence of recursion. Unlike other logic programs in which evaluation of a recursive predicate may fail to terminate, in Datalog the meaning of a recursive predicate is simply given by the least fixed point of the recursive equation it defines. As an example, consider the recursive predicate
predicate p(int X,int Y){q(X,Y) or (p(X,Z) and q(Z,Y))}
where q denotes (say) the relation {(1,2), (2,3), (3,4)}. Then p denotes the solution of the relation equation P=q∪P;q, in which ; stands for relational composition. This is just the transitive closure of q, so the relation p is simply
p={(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)}
This least fixed point interpretation of Datalog programs makes it easy to find the value of any predicate. For instance, consider
predicate p(int X){p (X)}
This predicate would be nonterminating as a Prolog program. However, in Datalog this is just the least solution of the equation P=P. As every relation satisfies this equation, the result is just the empty relation.
More precisely, the meaning of a Datalog program can be defined as follows. First, break the program up into components, where each component represents a recursive cycle between predicates (formally, a strongly-connected component in the call graph). Evaluation proceeds bottom-up, starting with extensional predicates and computing each layer as a least fixed point as above.
There are two technical restrictions to the use of recursion in Datalog. The first is known as stratification, and is necessary to deal with negation properly. The problem can be illustrated by this simple example:
predicate p(@person X){not(p(X))}
What should this predicate mean? It is defined as its own complement, so a person lies in p iff it she does not lie in p. There is no relation satisfying this property, so we cannot assign a simple relational interpretation to this program. To avoid this issue, we only consider ‘stratified’ Datalog. In this fragment of Datalog, negation cannot be used inside a recursive cycle. That is, a cycle through mutually recursive predicates cannot include negation. This is not a problem in practice, and stratification is not a substantial obstacle to expressiveness.
A similar problem is posed by our use of expressions, which does not lie in the scope of classical Datalog. While expressions increase the power of the language, their interaction with recursion is problematic. For instance, consider the following:
predicate p(int Y){Y=0 or (Y=Z+1 and p(X,Z))}
Clearly 0 lies in p. Therefore 1 must also lie in p from the recursive clause, and in this manner every number n lies in p. The use of expressions in recursive calls may therefore lead to infinite relations, and thus nontermination. In .QL this may also lead to nonterminating queries, and so care must be used when using arithmetic expressions in recursive calls—if, as in the above example, the expression can create new values for each recursive call, then the query may be non-terminating.
Translating .QL
The precise semantics of .QL programs are defined by their translation into Datalog programs. The overall structure of .QL programs mirrors that of Datalog programs. In particular, the query in a .QL program is translated into a Datalog query, while methods and classless predicates are translated to Datalog intensional predicates.
Translating Queries
The general form of a .QL query (ignoring order by clauses, which merely amount to a post-processing step) is:
from T1 x1, T2 x2, . . ., Tn xn
where formula
select e1, e2, . . . , ek
where each ei is an expression, and each xi is a declared variable of type Ti.
It is straightforward to translate this to a Datalog query, which is just a standard predicate. The resulting relation has k parameters (one for each selected expression), and so the query predicate has k parameters. The variables x1 through xn can be introduced as local variables, defined by an existential quantifier. As a result, the Datalog translation of the above query, omitting types, is:
predicate p(res1, res2, . . . , resk) {
exists (T1 x1, T2 x2, . . . , Tn xn |
formula2
and res1 = e1
and res2 = e2
and . . .
and resk = ek
)
}
where formula2 is obtained from formula by translating away all non-Datalog features of .QL, and in particular method calls, as described below.
Translating Classes
Classes are translated into individual Datalog predicates, representing constructors, methods and class predicates. In most cases the translation is straightforward, the key aspect being the translation of method calls.
A .QL method is merely a particular kind of Datalog predicate involving two special variables—this and result. The this variable holds the value that is a member of the class, while the result variable holds the result of the method. As an example, consider the following method to compute a string representation of an employee:
class Employee extends @person {
. . .
string toString( ) {result=“employee:”+this.getName( ) }
}
This is translated into the following Datalog predicate:
predicate Employee_toString(Employee this, string result)
{ exists(string name |
Employee_getName(this,name) and
result=“employee:”+name)
}
The translation of parameterless methods extends to methods taking an arbitrary number of parameters, in which case the two parameters this and result are simply added to the list of parameters. Apart from the translation of method inheritance, which we will describe shortly, there are few differences between the body of the method and the body of the generated predicate. Class predicates are similar, but as predicates do not return a value, the result variable is not used.
The above example highlights one of the crucial advantages of .QL methods over Datalog predicates, in addition to extensibility. In Datalog, it is necessary to name each intermediate result, as is the case with the name variable in the above example, which had to be declared with exists. In contrast, methods returning (many) values allow queries to be written in a much more concise and readable manner.
Finally, constructors are simply translated to Datalog predicates denoting the character of each class. For instance, consider the definition of the Manager class discussed earlier:
class Manager extends Employee {
Manager( ) { manages(this,_) }
. . .
}
The constructor for this class is translated into a predicate defining precisely those persons who are Managers. These are the Employees that additionally occur in the first column of the manages relation in the database:
predicate Manager(Employee this) {
manages(this,_)
}
When a class inherits from multiple classes, the translation is a little more complicated. Consider the class
class ParttimeManager extends Parttimer, Manager { . . . }
This class extends both Parttimer and Manager, and thus a person is a ParttimeManager exactly when she is both a Parttimer and a Manager. This is encoded in the generated characteristic predicate for ParttimeManager:
predicate ParttimeManager(Manager this) {Parttimer (this)}
Despite the fact that ParttimeManager does not define a constructor, it restricts the range of values that it encompasses by inheritance, and thus this characteristic predicate must be generated.
Characteristic predicates are also used for the translation of casts and instanceof tests. To guarantee an expression e to be of a specific type T, a call to the characteristic predicate of T is generated with the expression e passed as its single argument.
Translating Method Calls
In the above, we have described the translation of methods into Datalog predicates with extra arguments this and result, and informally shown some method calls translated into calls to the generated predicates. In our examples, the translation was straightforward, as the type of the receiver was known, and so it was immediately apparent which predicate should be called. However, as .QL uses virtual dispatch, the method that is actually used depends on the value it is invoked on, and the previous translation scheme cannot work in general.
To illustrate the translation of method dispatch in .QL, consider the following class hierarchy:
class All {
All( ) { this=1 or this=2 or this=3 or this=4 }
string foo( ) { result = “A” }
}
class OneOrTwo extends All {
OneOrTwo( ) {this=1 or this=2 }
string foo( ) {result =“B” }
}
class TwoOrThree extends All {
TwoOrThree( ) {this=2 or this=3 }
string foo( ) {result=“C” }
}
As we have seen previously, each of the implementations of foo is translated into a Datalog predicate:
predicate All_foo(All this, string result) { result = “A” }
predicate OneOrTwo_foo(OneOrTwo this, string result) {
result = “B”
}
predicate TwoOrThree foo(TwoOrThree this, string result) {
result = “C”
}
However, when a call to the foo method is encountered, the appropriate methods must be chosen, depending on the value of the receiver of the call. .QL method dispatch selects the most specific methods, of which there may be several due to overlapping classes, and returns results from all most specific methods. Only the most specific methods are considered, so that a method is not included if it is overridden by a matching method.
This virtual dispatch mechanism is implemented by defining a dispatch predicate for each method, testing the receiver against the relevant types and choosing appropriate methods. Testing the type of the receiver is achieved by invoking the characteristic predicate for each possible class, leading to the following dispatch method for foo:
predicate Dispatch_foo(All this, string result) {
OneOrTwo_foo(this, result)
or TwoOrThree_foo(this, result)
or (not(OneOrTwo(this)) and not(TwoOrThree(this))
and All_foo(this, result))
}
Let us examine this dispatch predicate a little more closely. The parameter this is given type All, as this is the most general possible type in this case. The body of the predicate consists of three possibly overlapping cases. In the first case, the foo method from OneOrTwo is called. Note that this only applies when this has type OneOrTwo, due to the type of the this parameter in OneOrTwo. As OneOrTwo does not have any subclasses, its foo method cannot be overridden, and whenever it is applicable it is necessarily the most specific. The second case is symmetrical, considering the class TwoOrThree. These cases are overlapping, if this=2, and so the method can return several results. Finally, the third case is the default case. If this did not match either of the specific classes OneOrTwo or TwoOrThree, the default implementation in All is chosen.
Suppose now that we extend the example by adding two further class definitions, namely
class OnlyTwo extends OneOrTwo, TwoOrThree {
foo( ) { result = “D” }
}
class AnotherTwo extends All {
AnotherTwo( ) { this = 2 }
foo( ) { result = “E” }
}
In this new hierarchy, we added two classes with exactly the same characteristic predicate. This changes method dispatch whenever this=2, as the newly introduced methods are more specific than previous methods for this case. To extend the previous example with these new classes, we simply lift out the new implementations of foo:
predicate OnlyTwo_foo(OnlyTwo this, string result) {
result = “D”
}
predicate AnotherTwo_foo(AnotherTwo this, string result) {
result = “E”
}
and change the dispatch predicate accordingly:
predicate Dispatch_foo(All this, string result) {
OnlyTwo_foo(this, result)
or AnotherTwo_foo(this, result)
or (not(OnlyTwo(this))
and OneOrTwo_foo(this, result))
or (not(OnlyTwo(this))
and TwoOrThree_foo(this, result))
or (not(OneOrTwo(this))
and not(TwoOrThree(this))
and not (AnotherTwo(this))
and All_foo(this, result))
}
The only changes, apart from the introduction of cases for the two new classes, is that the existing cases for OneOrTwo, TwoOrThree and All must be amended to check whether the method is indeed the most specific one.
Finally, a method call adorned with the chaining operator + or * is translated to a call to a predicate encoding the transitive closure, or reflexive transitive closure respectively, of the original method call. For instance, d.getAChild+( )translates to a call to:
predicate getAChildTC (Department X, Department Y) {
Department_getAChild(X,Y) or
(getAChildTC (X,Z) and Department_getAChild(Z,Y))
}
One particular way the invention can be realized is depicted in
Other possible realizations are obtained by replacing SQL and the database in
Examples of such other search engines are a search engine for XML documents, a text-based search engine, an API for accessing web services, anAPI for querying information on a social networking site, any other search engine for social networking sites, an online patent database search engine, a search engine for financial data, enterprise search engines, tools for software asset management (which store software assets in some searchable format), and so on.
Non-Limiting Hardware Examples
Overall, the present invention can be realized in hardware or a combination of hardware and software. The processing system according to a preferred embodiment of the present invention can be realized in a centralized fashion in one computer system, or in a distributed fashion where different elements are spread across several interconnected computer systems and image acquisition sub-systems. Any kind of computer system—or other apparatus adapted for carrying out the methods described herein—is suited. A typical combination of hardware and software is a general-purpose computer system with a computer program that, when loaded and executed, controls the computer system such that it carries out the methods described herein.
An embodiment of the processing portion of the present invention can also be embedded in a computer program product, which comprises all the features enabling the implementation of the methods described herein, and which when loaded in a computer system—is able to carry out these methods. Computer program means or computer programs in the present context mean any expression, in any language, code or notation, of a set of instructions intended to cause a system having an information processing capability to perform a particular function either directly or after either or both of the following a) conversion to another language, code or, notation; and b) reproduction in a different material form.
Computer system 1200 also optionally includes a communications interface 1224. Communications interface 1224 allows software and data to be transferred between computer system 1200 and external devices. Examples of communications interface 1224 include a modem, a network interface (such as an Ethernet card), a communications port, a PCM-CIA slot and card, etc. Software and data transferred via communications interface 1224 are in the form of signals which may be, for example, electronic, electromagnetic, optical, or other signals capable of being received by communications interface 1224. These signals are provided to communications interface 1224 via a communications path (i.e., channel) 1226. This channel 1226 carries signals and is implemented using wire or cable, fiber optics, a phone line, a cellular phone link, an RF link, and/or other communications channels.
Although specific embodiments of the invention have been disclosed, those having ordinary skill in the art will understand that changes can be made to the specific embodiments without departing from the spirit and scope of the invention. The scope of the invention is not to be restricted, therefore, to the specific embodiments. Furthermore, it is intended that the appended claims cover any and all such applications, modifications, and embodiments within the scope of the present invention.
Hajiyev, Elnar, de Moor, Oege, Verbaere, Mathieu
Patent | Priority | Assignee | Title |
9996583, | May 25 2017 | Microsoft Technology Licensing, LLC | Differential recursive evaluation of recursive aggregates |
Patent | Priority | Assignee | Title |
5761493, | Apr 30 1990 | Texas Instruments Incorporated | Apparatus and method for adding an associative query capability to a programming language |
5765159, | Dec 29 1994 | International Business Machines Corporation | System and method for generating an optimized set of relational queries for fetching data from a relational database management system in response to object queries received from an object oriented environment |
5794231, | Dec 28 1995 | International Business Machines Corporation | Method for application-program database interface |
5905982, | Apr 04 1997 | International Business Machines Corporation | Handling null values in SQL queries over object-oriented data |
6105035, | Feb 17 1998 | WSOU Investments, LLC | Method by which notions and constructs of an object oriented programming language can be implemented using a structured query language (SQL) |
6173290, | Sep 26 1996 | Sun Microsystems, Inc. | Method and apparatus for coupling object state and behavior in a database management system |
6748377, | Oct 18 2000 | International Business Machines Corporation | Facilitating query pushdown in a multi-tiered database environment |
6763341, | Jul 19 2001 | Object-oriented knowledge base system | |
6971085, | Aug 31 2000 | International Business Machines Corporation | Object oriented structured query language (OOSQL) support for enterprise java beans |
20040193575, | |||
20040230584, | |||
20060190461, | |||
20070038651, | |||
20090077001, | |||
20100205171, |
Executed on | Assignor | Assignee | Conveyance | Frame | Reel | Doc |
Oct 08 2015 | Semmle Limited | (assignment on the face of the patent) | / | |||
Nov 29 2019 | Semmle Limited | GITHUB SOFTWARE UK LTD | CHANGE OF NAME SEE DOCUMENT FOR DETAILS | 051244 | /0305 | |
Jan 16 2020 | GITHUB SOFTWARE UK LTD | Microsoft Technology Licensing, LLC | ASSIGNMENT OF ASSIGNORS INTEREST SEE DOCUMENT FOR DETAILS | 051710 | /0252 |
Date | Maintenance Fee Events |
Jan 22 2020 | BIG: Entity status set to Undiscounted (note the period is included in the code). |
Mar 24 2021 | M1552: Payment of Maintenance Fee, 8th Year, Large Entity. |
Date | Maintenance Schedule |
Sep 05 2020 | 4 years fee payment window open |
Mar 05 2021 | 6 months grace period start (w surcharge) |
Sep 05 2021 | patent expiry (for year 4) |
Sep 05 2023 | 2 years to revive unintentionally abandoned end. (for year 4) |
Sep 05 2024 | 8 years fee payment window open |
Mar 05 2025 | 6 months grace period start (w surcharge) |
Sep 05 2025 | patent expiry (for year 8) |
Sep 05 2027 | 2 years to revive unintentionally abandoned end. (for year 8) |
Sep 05 2028 | 12 years fee payment window open |
Mar 05 2029 | 6 months grace period start (w surcharge) |
Sep 05 2029 | patent expiry (for year 12) |
Sep 05 2031 | 2 years to revive unintentionally abandoned end. (for year 12) |