Hello Kuppitz,

> I don't think it's a good idea to keep this mindset for TP4; NULLs are too
> important in RDBMS. I don't know, maybe you can convince SQL people that
> dropping a value is the same as setting its value to NULL. It would work
> for you and me and everybody else who's familiar with Gremlin, but SQL
> people really love their NULLs….

Hmm……. I don’t like nulls. Perhaps with time a clever solution will emerge. ????

> I'd prefer to just have special accessors for these. E.g. g.V().meta("id").
> At least valueMaps would then only have String-keys.
> I see the issue with that (naming collisions), but it's still better than
> the enums in my opinion (which became a pain when started to implement
> GLVs).

So, TSymbols are not Java enums. They are simply a “primitive”-type that will 
have a serialization like:

        symbol[id]

Meaning, that people can make up Symbols all day long without having to update 
serializers. How I see them working is that they are Strings prefixed with #.

g.V().outE()             <=>   g.V().values(“#outE”)
g.V().id()               <=>   g.V().value(“#id”)
g.V().hasLabel(“person") <=>   g.V().has(“#label”,”person”)

Now that I type this out, perhaps we don’t even have a TSymbol-class. Instead, 
any String that starts with # is considered a symbol. Now watch this:

g.V().label()  <=>   g.V().value(“#label”)
g.V().labels() <=>   g.V().values(“#label”)

In this way, we can support Neo4j multi-labels as a Neo4jVertex’s #label-Key 
references a TSequence<String>.

g.V(1).label() => TSequence<String>
g.V(1).labels() => String, String, String, …
g.V(1).label().add(“programmer”)
g.V(1).label().drop(“person”)

So we could do “meta()”, but then you need respective “hasXXX”-meta() methods. 
I think #symbol is easiest .. ?

> Also, what I'm wondering about now: Have you thought about Stored
> Procedures and Views in RDBMS? Views can be treated as tables, easy, but
> what about stored procedures? SPs can be found in many more DBMS, would be
> bad to not support them (or hack something ugly together later in the
> development process).

I’m not super versed in RDBMS technology. Can you please explain to me how to 
create a StoreProcedure and the range of outputs a StoredProcedure produces? 
From there, I can try and “Bytecode-ize” it.

Thanks Kuppitz,
Marko.

http://rredux.com <http://rredux.com/>




> On Mon, Apr 29, 2019 at 7:34 AM Marko Rodriguez <[email protected] 
> <mailto:[email protected]>>
> wrote:
> 
>> Hi,
>> 
>> *** This email is primarily for Josh (and Kuppitz). However, if others are
>> interested… ***
>> 
>> So I did a lot of thinking this weekend about structure/ and this morning,
>> I prototyped both graph/ and rdbms/.
>> 
>> This is the way I’m currently thinking of things:
>> 
>>        1. There are 4 base types in structure/.
>>                - Primitive: string, long, float, int, … (will constrain
>> these at some point).
>>                - TTuple<K,V>: key/value map.
>>                - TSequence<V>: an iterable of v objects.
>>                - TSymbol: like Ruby, I think we need “enum-like” symbols
>> (e.g., #id, #label).
>> 
>>        2. Every structure has a “root.”
>>                - for graph its TGraph implements TSequence<TVertex>
>>                - for rdbms its a TDatabase implements
>> TTuple<String,TTable>
>> 
>>        3. Roots implement Structure and thus, are what is generated by
>> StructureFactory.mint().
>>                - defined using withStructure().
>>                - For graph, its accessible via V().
>>                - For rdbms, its accessible via db().
>> 
>>        4. There is a list of core instructions for dealing with these
>> base objects.
>>                - value(K key): gets the TTuple value for the provided key.
>>                - values(K key): gets an iterator of the value for the
>> provided key.
>>                - entries(): gets an iterator of T2Tuple objects for the
>> incoming TTuple.
>>                - hasXXX(A,B): various has()-based filters for looking
>> into a TTuple and a TSequence
>>                - db()/V()/etc.: jump to the “root” of the withStructure()
>> structure.
>>                - drop()/add(): behave as one would expect and thus.
>> 
>> ————
>> 
>> For RDBMS, we have three interfaces in rdbms/.
>> (machine/machine-core/structure/rdbms)
>> 
>>        1. TDatabase implements TTuple<String,TTable> // the root
>> structure that indexes the tables.
>>        2. TTable implements TSequence<TRow<?>> // a table is a sequence
>> of rows
>>        3. TRow<V> implements TTuple<String,V>> // a row has string column
>> names
>> 
>> I then created a new project at machine/structure/jdbc). The classes in
>> here implement the above rdbms/ interfaces/
>> 
>> Here is an RDBMS session:
>> 
>> final Machine machine = LocalMachine.open();
>> final TraversalSource jdbc =
>>        Gremlin.traversal(machine).
>>                        withProcessor(PipesProcessor.class).
>>                        withStructure(JDBCStructure.class,
>> Map.of(JDBCStructure.JDBC_CONNECTION, "jdbc:h2:/tmp/test"));
>> 
>> System.out.println(jdbc.db().toList());
>> System.out.println(jdbc.db().entries().toList());
>> System.out.println(jdbc.db().value("people").toList());
>> System.out.println(jdbc.db().values("people").toList());
>> System.out.println(jdbc.db().values("people").value("name").toList());
>> System.out.println(jdbc.db().values("people").entries().toList());
>> 
>> This yields:
>> 
>> [<database#conn1: url=jdbc:h2:/tmp/test user=>]
>> [PEOPLE:<table#PEOPLE>]
>> [<table#people>]
>> [<row#PEOPLE:1>, <row#PEOPLE:2>]
>> [marko, josh]
>> [NAME:marko, AGE:29, NAME:josh, AGE:32]
>> 
>> The bytecode of the last query is:
>> 
>> [db(<database#conn1: url=jdbc:h2:/tmp/test user=>), values(people),
>> entries]
>> 
>> JDBCDatabase implements TDatabase, Structure.
>>        *** JDBCDatabase is the root structure and is referenced by db()
>> *** (CRUCIAL POINT)
>> 
>> Assume another table called ADDRESSES with two columns: name and city.
>> 
>> 
>> jdbc.db().values(“people”).as(“x”).db().values(“addresses”).has(“name”,eq(path(“x”).by(“name”))).value(“city”)
>> 
>> The above is equivalent to:
>> 
>> SELECT city FROM people,addresses WHERE people.name=addresses.name
>> 
>> If you want to do an inner join (a product), you do this:
>> 
>> 
>> jdbc.db().values(“people”).as(“x”).db().values(“addresses”).has(“name”,eq(path(“x”).by(“name”))).as(“y”).path(“x”,”y")
>> 
>> The above is equivalent to:
>> 
>> SELECT * FROM addresses INNER JOIN people ON people.name=addresses.name
>> 
>> NOTES:
>>        1. Instead of select(), we simply jump to the root via db() (or
>> V() for graph).
>>        2. Instead of project(), we simply use value() or values().
>>        3. Instead of select() being overloaded with by() join syntax, we
>> use has() and path().
>>                - like TP3 we will be smart about dropping path() data
>> once its no longer referenced.
>>        4. We can also do LEFT and RIGHT JOINs (haven’t thought through
>> FULL OUTER JOIN yet).
>>                - however, we don’t support ‘null' in TP so I don’t know
>> if we want to support these null-producing joins. ?
>> 
>> LEFT JOIN:
>>        * If an address doesn’t exist for the person, emit a “null”-filled
>> path.
>> 
>> jdbc.db().values(“people”).as(“x”).
>>  db().values(“addresses”).as(“y”).
>>    choose(has(“name”,eq(path(“x”).by(“name”))),
>>      identity(),
>>      path(“y”).by(null).as(“y”)).
>>  path(“x”,”y")
>> 
>> SELECT * FROM addresses LEFT JOIN people ON people.name=addresses.name
>> 
>> RIGHT JOIN:
>> 
>> jdbc.db().values(“people”).as(“x”).
>>  db().values(“addresses”).as(“y”).
>>    choose(has(“name”,eq(path(“x”).by(“name”))),
>>      identity(),
>>      path(“x”).by(null).as(“x”)).
>>  path(“x”,”y")
>> 
>> 
>> SUMMARY:
>> 
>> There are no “low level” instructions. Everything is based on the standard
>> instructions that we know and love. Finally, if not apparent, the above
>> bytecode chunks would ultimately get strategized into a single SQL query
>> (breadth-first) instead of one-off queries (depth-first) to improve
>> performance.
>> 
>> Neat?,
>> Marko.
>> 
>> http://rredux.com <http://rredux.com/> <http://rredux.com/ 
>> <http://rredux.com/>>

Reply via email to