3 疑似列
Oracle Continuous Query Language (Oracle CQL)の疑似列のリファレンスを提供します。疑似列は、問い合せることはできますが、イベントの作成元であるデータの一部ではありません。
3.2 ELEMENT_TIME疑似列
CQLでは、すべてのストリーム・イベントにタイムスタンプが関連付けられています。ELEMENT_TIME
疑似列は、ストリーム・イベントのタイムスタンプを返します。ELEMENT_TIME
疑似列のデータ型は、Oracle CQLネイティブ・タイプのbigint
です。ELEMENT_TIME
から返されるタイムスタンプ値の単位はナノ秒です。
注意:
ELEMENT_TIME
は、Oracle CQLリレーションのメンバーではサポートされません。詳細は、「ストリームとリレーション」を参照してください。
この項の内容は、次のとおりです。
詳細については、以下を参照:
3.2.1 ELEMENT_TIME疑似列の値について
各ストリーム・イベントのELEMENT_TIME
の値は、そのイベントのタイムスタンプです。ストリーム・イベントのタイムスタンプは、ストリームの定義とソースによって異なります。
3.2.1 システム・タイムスタンプ付きストリームの場合のELEMENT_TIME
ソース・ストリームがシステム・タイムスタンプによってタイムスタンプが付けられたストリームの場合、ストリーム・イベントのタイムスタンプはSystem.nanoTime()
を計算することで割り当てられます。イベントごとのELEMENT_TIME
疑似列により、イベントのタイムスタンプが出力されます。
たとえば、システムによってタイムスタンプが付けられたストリームtktest_S1(c1 integer)
が定義されているとします。
select ELEMENT_TIME, to_timestamp(ELEMENT_TIME) from tktest_S1
Input (c1) Output (timestamp: element_time, to_timestamp(element_time))
10 12619671878392750:+ 12619671878392750,05/26/1970 18:27:51
20 12619671889193750:+ 12619671889193750,05/26/1970 18:27:51
30 12619671890093750:+ 12619671890093750,05/26/1970 18:27:51
40 12619671891399750:+ 12619671891399750,05/26/1970 18:27:51
50 12619671896472750:+ 12619671896472750,05/26/1970 18:27:51
注意:
タイムスタンプはSystem.nanoTime()
を計算することで算出されるため、出力は実行ごとに様々であり、マシンによっても異なります。
3.2.1.2 アプリケーション・タイムスタンプ付きストリームの場合のELEMENT_TIME
ソース・ストリームがアプリケーションによってタイムスタンプが付けられたストリームの場合、ストリーム・イベントのタイムスタンプはアプリケーションのタイムスタンプ式を計算することで割り当てられます。計算されたタイムスタンプ値の単位は常にナノ秒になります。ELEMENT_TIME
疑似列により、イベントのタイムスタンプが出力されます。
たとえば、アプリケーションによってタイムスタンプが付けられたストリームtktest_S1(C1 integer, c2 bigint)
が定義されていて、アプリケーションのタイムスタンプ式がc2*1000000000L
だとします。
select ELEMENT_TIME, to_timestamp(ELEMENT_TIME) from tktest_S1
Input(c1,c2) Output(timestamp: element_time, to_timestamp(element_time))
10, 10 10000000000:+ 10000000000,12/31/1969 17:00:10
20, 20 20000000000:+ 20000000000,12/31/1969 17:00:20
30, 30 30000000000:+ 30000000000,12/31/1969 17:00:30
40, 40 40000000000:+ 40000000000,12/31/1969 17:00:40
50, 50 50000000000:+ 50000000000,12/31/1969 17:00:50
前述の問合せでは、各イベントのタイムスタンプは、それぞれのイベントのc2*1000000000L
を計算することで算出されています。ELEMENT_TIME
は、イベントのタイムスタンプと同じであることがわかります。
3.2.1.2.1 intまたはbigintに対して評価を行う派生タイムスタンプ式
派生タイムスタンプ式が、Oracle CQLネイティブ・タイプint
に対して評価を行う場合、対応するbigint
値として結果が返されます。この式がOracle CQLネイティブ・タイプbigint
に対して評価を行う場合は、その値がそのまま返されます。
3.2.1.3 インラインCQLビューのELEMENT_TIME
ソース・ストリームがインラインCQLビューから受け取られた場合、ストリーム・イベントのタイムスタンプはビューの問合せによって算出されます。ELEMENT_TIME
により、イベントのタイムスタンプが出力されます。ELEMENT_TIME
の単位は常にナノ秒になり、データ型はCQLネイティブ・タイプのbigint
になります。
たとえば、アプリケーションによってタイムスタンプが付けられたストリームtktest_S1(C1 integer, c2 bigint)
が定義されていて、アプリケーションのタイムスタンプ式がc2*1000000000L
だとします。
ビューV
は、問合せISTREAM(SELECT * FROM SYSTS_STREAM[RANGE 1 MINUTE SLIDE 15 SECONDS]
を使用することで定義されています。
select ELEMENT_TIME, to_timestamp(ELEMENT_TIME) from V
Input(c1,c2) Output(timestamp: element_time, to_timestamp(element_time))
10, 10 15000000000:+ 15000000000,12/31/1969 17:00:15
20, 20 30000000000:+ 30000000000,12/31/1969 17:00:30
30, 30 30000000000:+ 30000000000,12/31/1969 17:00:30
40, 40 45000000000:+ 45000000000,12/31/1969 17:00:45
50, 50 50000000000:+ 50000000000,12/31/1969 17:00:55
3.2.2 Oracle CQL問合せ内での_TIME疑似列の使用
この項では、様々な問合せでELEMENT_TIME
を使用する方法を説明します。
3.2.2.1 SELECTでのELEMENT_TIMEの使用
次の例は、select文でELEMENT_TIME
擬似列を使用する方法を示します。ストリームS1
のスキーマは(c1 integer)
です。関数to_timestamp
を使用して、Long
値をタイムスタンプ値に変換しています。
<query id="q4"><![CDATA[ select c1, to_timestamp(element_time) from S1[range 10000000 nanoseconds slide 10000000 nanoseconds] ]]></query>
Timestamp Tuple 8000 80 9000 90 13000 130 15000 150 23000 230 25000 250
Timestamp Tuple Kind Tuple 8000 + 80,12/31/1969 17:00:08 8010 - 80,12/31/1969 17:00:08 9000 + 90,12/31/1969 17:00:09 9010 - 90,12/31/1969 17:00:09 13000 + 130,12/31/1969 17:00:13 13010 - 130,12/31/1969 17:00:13 15000 + 150,12/31/1969 17:00:15 15010 - 150,12/31/1969 17:00:15 23000 + 230,12/31/1969 17:00:23 23010 - 230,12/31/1969 17:00:23 25000 + 250,12/31/1969 17:00:25 25010 - 250,12/31/1969 17:00:25
問合せにGROUP BY
句が含まれる場合、SELECT
文で直接ELEMENT_TIME
疑似列を使用することはできません。かわりに、「GROUP BYでのELEMENT_TIMEの使用」で説明するようにビューを使用します。
3.2.2.2 GROUP BYでのELEMENT_TIMEの使用
GROUP BY
句があるため、問合せのSELECT
文でELEMENT_TIME
を使用することはできません。
<query id="Q1"><![CDATA[
SELECT R.queryText AS queryText, COUNT(*) AS queryCount FROM queryEventChannel [range 30 seconds] AS R GROUP BY queryText
]]></query>
かわりに、ビューを作成します。V1
に相当する派生したストリームには、特定のqueryText
グループに対して(queryText
、queryCount
、maxTime
)が変わるたびに、ストリーム要素が含められます。
<view id="V1"><![CDATA[
ISTREAM ( SELECT R.queryText AS queryText, COUNT(*) AS queryCount, MAX(R.ELEMENT_TIME) as maxTime FROM queryEventChannel [range 30 seconds] AS R GROUP BY queryText )
]]></view>
注意:
ビューV1の出力要素に関連付けられている要素時間は、その出力イベントの属性maxTime
の値と同じである必要はありません。
たとえば、ウィンドウがスライドし、 queryEventChannel
入力ストリームからの要素がそのウィンドウで期限切れとなった場合に、queryText
グループのqueryCount
が変わり、出力となります。ただし、そのウィンドウに入る入力ストリームqueryEventChannel
からの新しいイベントがないので、そのウィンドウ内のすべてのイベント間のmaxTime
は変わらず、この出力イベントのmaxTime
属性の値は、以前の出力イベントのこの属性値と同じになります。
ただし、出力イベントのELEMENT_TIME
は、出力イベントのELEMENT_TIME
は出力イベントのmaxTime
属性の値とは異なるなど、入力ストリームからの最新イベントとは異なり、イベントがウィンドウで期限切れとなった瞬間と同じになります。
ビューV1の出力イベントのELEMENT_TIME
を選択するには、問合せを作成します。
<query id="Q1"><![CDATA[
SELECT queryText, queryCount, ELEMENT_TIME as eventTime FROM V1
]]></query>
3.2.2.3 PATTERNでのELEMENT_TIMEの使用
次の例は、pattern問合せでELEMENT_TIME
疑似列を使用する方法を示します。Nth.status
の値が>= F.status
で、そのタプルのNth.ELEMENT_TIME
値と最後にF
に一致したタプルとの差がjava.lang.Math.Bigint(Long)
として指定された間隔に満たない場合、タプルまたはイベントは相関変数Nth
に一致します。
... PATTERN (F Nth+? L) DEFINE Nth AS Nth.status >= F.status AND Nth.ELEMENT_TIME - F.ELEMENT_TIME < 10000000000L, L AS L.status >= F.status AND count(Nth.*) = 3 AND L.ELEMENT_TIME - F.ELEMENT_TIME < 10000000000L ...
3.3 ORA_QUERY_ID疑似列
着信イベント分割するには、出力に含まれる問合せ名または識別子の情報が必要になります。クエリの名前または識別子は、タプル属性の一部であり、TupleValueのgetter APIで呼び出すことになります。
この目的のために、Oracle CQLには、問合せの出力に含まれる問合せ名にアクセスする新しい疑似列ORA_QUERY_IDが用意されています。
次に示すように、CQL問合せのSELECT
リストで前述の疑似列を使用すると、出力タプルに含まれる問合せ名を取得できます。
CREATE QUERY Q1 AS SELECT ORA_QUERY_ID from STREAM;
前述の問合せQ1
の出力イベントごとに、問合せ名または識別子と等しい値を持つ属性が1つのみ含まれます。前述の問合せでは、STREAM
への着信イベントごとに、アプリケーションはQ1
の値を保持する1つの属性を含む出力タプルを送信します。
CREATE QUERY Q1 AS
SELECT ORA_QUERY_ID, stock_quote, stock_price FROM StockStream;
次に、入力値と出力値を示します。
Input(stock_quote, stock_price) Output(ORA_QUERY_ID, stock_quote, stock_price)
ORCL, 34 Q1, ORCL, 34
MSFT, 38 Q1, MSFT, 38
CSCO, 21 Q1, CSCO, 21
INTC, 24 Q1, INTC, 24
FB, 48 Q1, FB, 48