Oracle 18c:
I can get SDO_ORDINATE_ARRAY
values from SDO_GEOMETRY
objects:
create table test_table (shape sdo_geometry);
insert into test_table (shape) values (sdo_geometry('linestring(10 20, 30 40, 50 60)'));
insert into test_table (shape) values (sdo_geometry('linestring(70 80, 90 100)'));
insert into test_table (shape) values (sdo_geometry('linestring(110 120, 130 140, 150 160, 170 180)'));
select
(shape).sdo_ordinates as sdo_ordinate_array
from
test_table
SDO_ORDINATE_ARRAY
------------------
MDSYS.SDO_ORDINATE_ARRAY(10, 20, 30, 40, 50, 60)
MDSYS.SDO_ORDINATE_ARRAY(70, 80, 90, 100)
MDSYS.SDO_ORDINATE_ARRAY(110, 120, 130, 140, 150, 160, 170, 180)
For what it's worth, this is what the definition of the MDSYS.SDO_ORDINATE_ARRAY
type looks like in SQL Developer:
create or replace TYPE SDO_ORDINATE_ARRAY AS VARRAY(1048576) OF NUMBER
Using a function, I want to convert the SDO_ORDINATE_ARRAYs
to the built-in VARRAY
datatype.
Reason: I want to experiment with storing the ordinates in a non-spatial Function-Based Index. If I understand correctly, only built-in datatypes are supported by FBIs, not Oracle-supplied types or abstract datatypes like SDO_ORDINATE_ARRAY
or SDO_GEOMETRY
.
For example, if I were to try to create the following FBI, it would fail:
create index sdo_ordinates_idx on test_table ((shape).sdo_ordinates);
Error:
Error starting at line : 12 in command -
create index sdo_ordinates_idx on test_table ((shape).sdo_ordinates)
Error report -
ORA-02327: cannot create index on expression with datatype ADT 🡄 ADT=Abstract Datatype
02327. 00000 - "cannot create index on expression with datatype %s"
*Cause: An attempt was made to create an index on a non-indexable
expression.
*Action: Change the column datatype or do not create the index on an
expression whose datatype is one of VARRAY, nested table, object,
LOB, or REF.
So I can't create an FBI on SDO_ORDINATE_ARRAY
. But I'm hoping I can convert the ordinates to a regular VARRAY
instead and make an FBI on those values.
Question:
Is there a way to convert SDO_ORDINATE_ARRAYs
to built-in VARRAYs
? (for the purpose of a function-based index)
I would prefer to store the ordinates as a proper VARRAYs
, rather than convert them to text. Reason: I believe the SDO_GEOMETRY
constructor only accepts array values, not text.
You state:
the definition of the
MDSYS.SDO_ORDINATE_ARRAY
type looks like in SQL Developer:create or replace TYPE SDO_ORDINATE_ARRAY AS VARRAY(1048576) OF NUMBER
and then ask:
Is there a way to convert
SDO_ORDINATE_ARRAY
s to built-inVARRAY
s? (for the purpose of a function-based index)
It is already a VARRAY
, you do not need to convert it.
The error message states:
Error report - ORA-02327: cannot create index on expression with datatype ADT 🡄 > ADT=Abstract Datatype 02327. 00000 - "cannot create index on expression with datatype %s" *Cause: An attempt was made to create an index on a non-indexable expression. *Action: Change the column datatype or do not create the index on an expression whose datatype is one of VARRAY, nested table, object, LOB, or REF.
In the action
section it specifically states that you cannot create an index on an expression whose datatype is one of VARRAY
or nested table. So what you are asking is impossible; you cannot create an index on a VARRAY
.
You state:
I would prefer to store the ordinates as a proper VARRAYs, rather than convert them to text. Reason: I believe the SDO_GEOMETRY constructor only accepts array values, not text.
Looking at the source:
select text
from all_source
where type = 'TYPE'
and owner = 'MDSYS'
and name = 'SDO_GEOMETRY'
ORDER BY line
The MDSYS_SDO_GEOMETRY
type has the constructors:
ADD CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkt IN CLOB, srid IN INTEGER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC PARALLEL_ENABLE, ADD CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkt IN VARCHAR2, srid IN INTEGER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC PARALLEL_ENABLE, ADD CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkb IN BLOB, srid IN INTEGER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC PARALLEL_ENABLE, ADD CONSTRUCTOR FUNCTION SDO_GEOMETRY(input_clob IN clob, auxiliary_info IN varchar2, crs IN VARCHAR2 DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC PARALLEL_ENABLE, ADD CONSTRUCTOR FUNCTION SDO_GEOMETRY(input_vchar IN varchar2, auxiliary_info IN varchar2, crs IN VARCHAR2 DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC PARALLEL_ENABLE CASCADE
None of those constructors take a VARRAY
argument. They all take strings (VARCHAR2
or CLOB
) except for one that takes a BLOB
.
db<>fiddle here