Skip to content
Advertisement

Why does CROSS JOIN LATERAL break up array’s SDO_GEOMETRY object into individual attributes?

Oracle 18c:

I have mapping software that has a limitation where it can only handle a single geometry column per table. If there are multiple geometry columns in a given table, then it will throw an error.

So, I want to find a way to add an additional geometry column to a table, but store it as a datatype that the mapping software doesn’t recognize — so it will ignore that column (TBD).

One idea is to store an SDO_GEOMETRY as an SDO_GEOMETRY_ARRAY datatype, since the software wouldn’t recognize SDO_GEOMETRY_ARRAY. I would always only store a single geometry in the array.

Similar to this:


Unsurprisingly, when I select from the array, it returns the entire array, not the SDO_GEOMETRY (even though there’s only a single value in the array).

So, I want to find an easy/succinct way to extract the SDO_GEOMETRY from the array.

I could use a custom function, which works as expected:

Or I could use a CROSS JOIN LATERAL:

That CROSS JOIN LATERAL works, but I don’t understand why it splits the SDO_GEOMETRY into it’s attribute components:

As such, I need to reconstruct the geometry from those attributes, like this: sdo_geometry(sdo_gtype, sdo_srid, sdo_point, sdo_elem_info, sdo_ordinates).

Reconstructing the SDO_GEOMETRY is slightly inconvenient. But also, I want to understand why that happens in the CROSS JOIN LATERAL, but not in the custom function.


Question:

Why does the CROSS JOIN LATERAL break up the array’s SDO_GEOMETRY object into individual attributes? (but the function doesn’t)

Advertisement

Answer

Why does the CROSS JOIN LATERAL break up the array’s SDO_GEOMETRY object into individual attributes? (but the function doesn’t)

CROSS JOIN LATERAL is treating the table collection expression as if it is an object-derived table (which it effectively is) and uses each object of the collection to form a row of a table and then the columns are the attributes of the object.

The function is returning a single object into one column of one row. They are very different operations.


If you want to get the objects that comprise each row from the table collection expression then use the VALUE function:

db<>fiddle here

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement