Skip to content

Commit 34b8f63

Browse files
committed
Add support for Interval datatypes (Issue #929)
1 parent 5b440f1 commit 34b8f63

30 files changed

+2675
-91
lines changed

doc/src/api_manual/oracledb.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,13 @@ instead of ``result.metadata[0].fetchType == 2001``.
119119
* - ``oracledb.DB_TYPE_INTERVAL_DS``
120120
- 2015
121121
- INTERVAL DAY TO SECOND
122+
123+
.. versionadded:: 6.8
122124
* - ``oracledb.DB_TYPE_INTERVAL_YM``
123125
- 2016
124126
- INTERVAL YEAR TO MONTH
127+
128+
.. versionadded:: 6.8
125129
* - ``oracledb.DB_TYPE_JSON``
126130
- 2027
127131
- JSON
@@ -3745,6 +3749,45 @@ node-oracledb, allowing use of new features.
37453749
BLOB columns with the ``IS JSON FORMAT OSON`` check constraint enabled
37463750
can now be fetched as JSON type columns when this property is set.
37473751

3752+
.. _intervalymclass:
3753+
3754+
Oracledb IntervalYM Class
3755+
=========================
3756+
3757+
Objects of this class are returned for columns of type INTERVAL YEAR TO MONTH
3758+
and can be passed to variables of type :ref:`oracledb.DB_TYPE_INTERVAL_YM
3759+
<oracledbconstantsdbtype>` The class contains two optional integer attributes,
3760+
``years`` and ``months``. These attributes can be set by a passed-in
3761+
JavaScript object containing these attributes.
3762+
3763+
If no JavaScript object is passed in or if these attributes are not defined in
3764+
the passed-in JavaScript object, they are set to *0* by default.
3765+
3766+
If these attribute values are not integers, then the ``NJS-007`` error is
3767+
thrown when the object is being created.
3768+
3769+
.. versionadded:: 6.8
3770+
3771+
.. _intervaldsclass:
3772+
3773+
Oracledb IntervalDS Class
3774+
=========================
3775+
3776+
Objects of this class are returned for columns of type INTERVAL DAY TO SECOND
3777+
and can be passed to variables of type :ref:`oracledb.DB_TYPE_INTERVAL_DS
3778+
<oracledbconstantsdbtype>` The class contains five optional integer
3779+
attributes, ``days``, ``hours``, ``minutes``, ``seconds``, and ``fseconds``
3780+
(fractional seconds denoted in nanoseconds). These attributes can be set by a
3781+
passed-in JavaScript object containing these attributes.
3782+
3783+
If no JavaScript object is passed in or if these attributes are not defined in
3784+
the passed-in JavaScript object, they are set to *0* by default.
3785+
3786+
If these attribute values are not integers, then the ``NJS-007`` error is
3787+
thrown when the object is being created.
3788+
3789+
.. versionadded:: 6.8
3790+
37483791
.. _jsonid:
37493792

37503793
Oracledb JsonId Class

doc/src/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ User Guide
2727
user_guide/tuning.rst
2828
user_guide/lob_data.rst
2929
user_guide/json_data_type.rst
30+
user_guide/interval_data_type.rst
3031
user_guide/xml_data_type.rst
3132
user_guide/vector_data_type.rst
3233
user_guide/objects.rst

doc/src/release_notes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ Common Changes
2121

2222
#) Added support for Oracle Database 23ai sparse vectors.
2323

24+
#) Added support for :ref:`interval year-to-month <intervalyeartomonth>` and
25+
:ref:`interval day-to-second <intervaldaytosecond>` database column types.
26+
See `Issue #929 <https://github.com/oracle/node-oracledb/issues/929>`__.
27+
2428
#) Fixed :attr:`~dbObject.length` property for the database object
2529
collection types, which was broken from node-oracledb 6.0.
2630

doc/src/user_guide/appendix_a.rst

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,11 @@ node-oracledb Thin and Thick modes. For more details see :ref:`modediff`.
267267
- Yes - Only read and write operations supported
268268
- Yes - Only read operations supported
269269
* - INTERVAL DAY TO SECOND data type (see :ref:`oracledbconstantsdbtype`)
270-
- No
271-
- No
270+
- Yes
271+
- Yes
272272
* - INTERVAL YEAR TO MONTH data type (see :ref:`oracledbconstantsdbtype`)
273-
- No
274-
- No
273+
- Yes
274+
- Yes
275275
* - Simple Oracle Document Access (SODA) (see :ref:`SODA <sodaoverview>`)
276276
- No
277277
- Yes
@@ -721,11 +721,11 @@ when binding numeric values.
721721
- DB_TYPE_TIMESTAMP_LTZ
722722
- Yes
723723
* - INTERVAL YEAR TO MONTH
724-
- Not supported
725-
- No
724+
- DB_TYPE_INTERVAL_YM
725+
- Yes
726726
* - INTERVAL DAY TO SECOND
727-
- Not supported
728-
- No
727+
- DB_TYPE_INTERVAL_DS
728+
- Yes
729729
* - RAW
730730
- DB_TYPE_RAW
731731
- Yes
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
.. _intervaltype:
2+
3+
*******************
4+
Using INTERVAL Data
5+
*******************
6+
7+
Oracle Database supports two INTERVAL data types that store time durations -
8+
INTERVAL YEAR TO MONTH and INTERVAL DAY TO SECOND. For more information on
9+
these data types, see `Oracle Interval Types <https://www.oracle.com/pls/topic
10+
/lookup?ctx=dblatest&id=GUID-7690645A-0EE3-46CA-90DE-C96DF5A01F8F>`__.
11+
12+
Node-oracledb does not support using INTERVAL data types in
13+
:ref:`Oracle Database Objects <dbobjectclass>`.
14+
15+
.. _intervalyeartomonth:
16+
17+
Using INTERVAL YEAR TO MONTH Data
18+
=================================
19+
20+
The INTERVAL YEAR TO MONTH data type stores a period of time using years and
21+
months.
22+
23+
To create a table with a column for INTERVAL YEAR TO MONTH data, for example:
24+
25+
.. code-block:: sql
26+
27+
CREATE TABLE TableIntervalYM (IntervalCol INTERVAL YEAR TO MONTH);
28+
29+
.. _insertintervalyeartomonth:
30+
31+
Inserting INTERVAL YEAR TO MONTH
32+
--------------------------------
33+
34+
You must create an IntervalYM object using :ref:`intervalymclass` to insert
35+
into an INTERVAL YEAR TO MONTH column. For example:
36+
37+
.. code-block:: javascript
38+
39+
const interval = new oracledb.IntervalYM();
40+
41+
This creates an Oracledb IntervalYM object with ``years`` and ``months``
42+
attributes set to *0*. You can also create an IntervalYM object with zero
43+
intervals using:
44+
45+
.. code-block:: javascript
46+
47+
const interval = oracledb.IntervalYM({});
48+
49+
You can define the optional ``years`` and ``months`` attributes in the
50+
IntervalYM class. For example, to create an Oracledb IntervalYM cobject with
51+
only the ``years`` attribute set to *2*:
52+
53+
.. code-block:: javascript
54+
55+
const interval = new oracledb.IntervalYM({ years: 2 });
56+
57+
An example of creating an IntervalYM object with ``years`` and ``months``
58+
attributes set to *1* and *6* respectively is shown below. This example is
59+
used in subsequent sections.
60+
61+
.. code-block:: javascript
62+
63+
const interval = new oracledb.IntervalYM({ years: 1, months: 6 });
64+
65+
If you specify non-integer values in the attributes of IntervalYM object, then
66+
the ``NJS-007`` error is raised.
67+
68+
You can insert IntervalYM objects into an INTERVAL YEAR TO MONTH column by
69+
binding as ``oracledb.DB_TYPE_YM``, for example:
70+
71+
.. code-block:: javascript
72+
73+
await connection.execute(
74+
`INSERT INTO TableIntervalYM VALUES (:bv)`,
75+
{ bv: { val: interval, type: oracledb.DB_TYPE_YM }
76+
);
77+
78+
.. _fetchintervalyeartomonth:
79+
80+
Fetching INTERVAL YEAR TO MONTH
81+
-------------------------------
82+
83+
To query an INTERVAL YEAR TO MONTH column, you can use:
84+
85+
.. code-block:: javascript
86+
87+
const result = await connection.execute(`SELECT * FROM TableIntervalYM`);
88+
console.log(result.rows[0][0]);
89+
90+
This query prints::
91+
92+
IntervalYM { years: 1, months: 6 }
93+
94+
.. _intervaldaytosecond:
95+
96+
Using INTERVAL DAY TO SECOND Data
97+
=================================
98+
99+
The INTERVAL DAY TO SECOND data type stores a period of time using days,
100+
hours, minutes, seconds, and fractional seconds.
101+
102+
To create a table with a column for INTERVAL DAY TO SECOND data, for example:
103+
104+
.. code-block:: sql
105+
106+
CREATE TABLE TableIntervalDS (IntervalDSCol INTERVAL DAY TO SECOND);
107+
108+
.. _insertintervaldaytosecond:
109+
110+
Inserting INTERVAL DAY TO SECOND
111+
--------------------------------
112+
113+
You must create an IntervalDS object using :ref:`intervaldsclass` to insert
114+
into an INTERVAL DAY TO SECOND column. For example:
115+
116+
.. code-block:: javascript
117+
118+
const interval = oracledb.IntervalDS();
119+
120+
This creates an Oracledb IntervalDS object with ``days``, ``hours``,
121+
``minutes``, ``seconds``, and ``fseconds`` (fractional seconds) attributes set
122+
to *0*. You can also create an IntervalDS object with zero intervals using:
123+
124+
.. code-block:: javascript
125+
126+
const interval = oracledb.IntervalDS({});
127+
128+
You can define the optional ``days``, ``hours``, ``minutes``, ``seconds``, and
129+
``fseconds`` attributes in the IntervalDS object. For example, to create an
130+
Oracledb IntervalDS object with the ``days``and ``seconds`` attributes set to
131+
*2* and *40* respectively is shown below. This example is used in subsequent
132+
sections.
133+
134+
.. code-block:: javascript
135+
136+
const data = new oracledb.IntervalDS({ days: 2, seconds: 40 });
137+
138+
If you specify non-integer values in the attributes of IntervalDS object, then
139+
the ``NJS-007`` error is raised.
140+
141+
You can insert IntervalDS objects into an INTERVAL DAY TO SECOND column by
142+
binding as ``oracledb.DB_TYPE_DS``, for example:
143+
144+
.. code-block:: javascript
145+
146+
await connection.execute(
147+
`INSERT INTO TableIntervalDS VALUES (:bv)`,
148+
{ bv: { val: data, type: oracledb.DB_TYPE_DS }
149+
);
150+
151+
.. _fetchintervaldaytosecond:
152+
153+
Fetching INTERVAL DAY TO SECOND
154+
-------------------------------
155+
156+
To query an INTERVAL DAY TO SECOND column, you can use:
157+
158+
.. code-block:: javascript
159+
160+
const result = await connection.execute(`SELECT * FROM TableIntervalDS`);
161+
console.log(result.rows[0][0]);
162+
163+
This query prints::
164+
165+
IntervalDS { days: 2, hours: 0, minutes: 0, seconds: 40, fseconds: 0 }

doc/src/user_guide/sql_execution.rst

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -811,8 +811,7 @@ used to change the default mapping, or override a global mapping, for
811811
individual columns.
812812

813813
Data types in ``SELECT`` statements that are unsupported give an error
814-
*NJS-010: unsupported data type in select list*. These include INTERVAL,
815-
BFILE, and XMLType types.
814+
*NJS-010: unsupported data type in select list*.
816815

817816
Details are in the following sections.
818817

@@ -954,8 +953,6 @@ ZONE columns are fetched as absolute dates. Note that JavaScript Date has
954953
millisecond precision. Therefore, timestamps will lose any sub-millisecond
955954
fractional part when fetched.
956955

957-
Oracle INTERVAL types are not supported.
958-
959956
.. versionchanged:: 6.0
960957

961958
Oracle Database DATE and TIMESTAMP types are now returned as JavaScript
@@ -1038,6 +1035,13 @@ For more information on time zones, see Oracle Support’s `Timestamps &
10381035
time zones - Frequently Asked Questions, Doc ID 340512.1
10391036
<https://support.oracle.com/epmos/faces/DocumentDisplay?id=340512.1>`__.
10401037

1038+
.. _intervalhandling:
1039+
1040+
Fetching Intervals
1041+
++++++++++++++++++
1042+
1043+
See :ref:`intervaltype`.
1044+
10411045
.. _fetchasstringhandling:
10421046

10431047
Fetching Numbers and Dates as String
@@ -1049,7 +1053,11 @@ columns <queryinglobs>`) queried by an application to be fetched as
10491053
strings instead of in native format. Allowing data to be fetched as
10501054
strings helps avoid situations where using JavaScript types can lead to
10511055
numeric precision loss, or where date conversion is unwanted. This
1052-
method can be used for CLOBs up to 1 GB in length.
1056+
method can be used for CLOBs up to 1 GB in length. The
1057+
:ref:`INTERVAL data types <intervalhandling>` cannot be fetched as strings
1058+
using :attr:`~oracledb.fetchAsString`. You can use
1059+
:ref:`fetch type handlers <fetchtypehandler>` to fetch interval data types as
1060+
strings.
10531061

10541062
For example, to force all dates and numbers used by queries in an
10551063
application to be fetched as strings:

lib/connection.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,9 @@ class Connection extends EventEmitter {
416416
bindInfo.type !== types.DB_TYPE_TIMESTAMP &&
417417
bindInfo.type !== types.DB_TYPE_TIMESTAMP_LTZ &&
418418
bindInfo.type !== types.DB_TYPE_TIMESTAMP_TZ &&
419-
bindInfo.type !== types.DB_TYPE_RAW) {
419+
bindInfo.type !== types.DB_TYPE_RAW &&
420+
bindInfo.type !== types.DB_TYPE_INTERVAL_YM &&
421+
bindInfo.type !== types.DB_TYPE_INTERVAL_DS) {
420422
errors.throwErr(errors.ERR_INVALID_TYPE_FOR_ARRAY_BIND);
421423
}
422424

0 commit comments

Comments
 (0)