<?xml version="1.0" encoding="UTF-8"?>
<!--
   ****************************************************************************
    MobilityDB Manual
    Copyright(c) MobilityDB Contributors

    This documentation is licensed under a Creative Commons Attribution-Share
    Alike 3.0 License: https://creativecommons.org/licenses/by-sa/3.0/
   ****************************************************************************
-->
<chapter xml:id="temporal_types_alpha">
	<title>Temporal Alphanumeric Types</title>

	<sect1 xml:id="talpha_notation">
		<title>Notation</title>
		<para>We presented in <xref linkend="ttype_notation"/> the notation used for defining the signature of the functions and operators for temporal alphanumeric types. We extend next this notations for temporal alphanumeric types.</para>
		<itemizedlist>
			<listitem>
				<para><varname>torder</varname> represents any temporal type whose base type has a total order defined, that is, <varname>tint</varname>, <varname>tfloat</varname>, or <varname>ttext</varname>,</para>
			</listitem>

			<listitem>
				<para><varname>talpha</varname> represents any temporal alphanumeric type, such as, <varname>tint</varname> or <varname>ttext</varname>,</para>
			</listitem>

			<listitem>
				<para><varname>tnumber</varname> represents any temporal number type, that is, <varname>tint</varname> or <varname>tfloat</varname>,</para>
			</listitem>

			<listitem>
				<para><varname>number</varname> represents any number base type, that is, <varname>integer</varname> or <varname>float</varname>,</para>
			</listitem>

			<listitem>
				<para><varname>numspan</varname> represents any number span type, that is, either <varname>intspan</varname> or <varname>floatspan</varname>,</para>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="talpha_conversions">
		<title>Conversions</title>
		<para>A temporal value can be converted into a compatible type using the notation <varname>CAST(ttype1 AS ttype2)</varname> or <varname>ttype1::ttype2</varname>.</para>
		<itemizedlist>
			<listitem xml:id="tnumber_bbox">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>valueSpan(tnumber)</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>timeSpan(tnumber)</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tbox(tnumber)</varname></primary></indexterm>
				<para>Convert a temporal number to a span or to a temporal bounding box</para>
				<para><varname>tnumber::{span,tbox}</varname></para>
				<para><varname>valueSpan(tnumber) → numspan</varname></para>
				<para><varname>timeSpan(tnumber) → tstzspan</varname></para>
				<para><varname>tbox(tnumber) → tbox</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[1@2001-01-01, 2@2001-01-03]'::intspan;
-- [1, 3)
SELECT tfloat '(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]'::floatspan;
-- (1, 3]
SELECT valueSpan(tfloat '(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]');
-- (1, 3]
SELECT timeSpan(tfloat 'Interp=Step;(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]');
-- (2001-01-01, 2001-01-05]
</programlisting>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[1@2001-01-01, 2@2001-01-03]'::tbox;
-- TBOXINT XT((1,2),[2001-01-01,2001-01-03])
SELECT tfloat '(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]'::tbox;
-- TBOXFLOAT XT((1,3),[2001-01-01,2001-01-05])
</programlisting>
			</listitem>

			<listitem xml:id="tbool_tint">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tint(tbool)</varname></primary></indexterm>
				<para>Convert between a temporal Boolean and a temporal integer</para>
				<para><varname>tbool::tint</varname></para>
				<para><varname>tint(tbool) → tint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tbool '[true@2001-01-01, false@2001-01-03]'::tint;
-- [1@2001-01-01, 0@2001-01-03]
</programlisting>
			</listitem>

			<listitem xml:id="tint_tfloat">
				<indexterm significance="normal"><primary><varname>::</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tfloat(tint)</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>tint(tfloat)</varname></primary></indexterm>
				<para>Convert between a temporal integer and a temporal float</para>
				<para><varname>tint::tfloat</varname></para>
				<para><varname>tfloat::tint</varname></para>
				<para><varname>tfloat(tint) → tfloat</varname></para>
				<para><varname>tint(tfloat) → tint</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[1@2001-01-01, 2@2001-01-03]'::tfloat;
-- Interp=Step;[1@2001-01-01, 2@2001-01-03]
SELECT tint '[1@2001-01-01, 2@2001-01-03, 3@2001-01-05]'::tfloat;
-- Interp=Step;[1@2001-01-01, 2@2001-01-03, 3@2001-01-05]
SELECT tfloat 'Interp=Step;[1.5@2001-01-01, 2.5@2001-01-03]'::tint;
-- [1@2001-01-01, 2@2001-01-03]
SELECT tfloat '[1.5@2001-01-01, 2.5@2001-01-03]'::tint;
-- ERROR:  Cannot cast temporal float with linear interpolation to temporal integer
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="talpha_accessors">
		<title>Accessors</title>
		<itemizedlist>
			<listitem xml:id="talpha_valueSet">
				<indexterm significance="normal"><primary><varname>valueSet</varname></primary></indexterm>
				<para>Return the values of the temporal number or geometry as a set</para>
				<para><varname>valueSet(tnumber, tgeo) → {numset,geoset}</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT valueSet(tint '[1@2001-01-01, 2@2001-01-03]');
-- {1, 2}
SELECT valueSet(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 4@2001-01-05)}');
-- {1, 2, 3, 4}
SELECT asText(valueSet(tgeompoint '{[Point(0 0)@2001-01-01, Point(0 1)@2001-01-02),
  [Point(0 1)@2001-01-03, Point(1 1)@2001-01-04)}'));
-- {"POINT(0 0)", "POINT(1 1)", "POINT(0 1)"}
SELECT asText(valueSet(tgeography 
  '{[Point(0 0)@2001-01-01, Linestring(0 0,1 1)@2001-01-02],
    [Point(1 1)@2001-01-03, Linestring(0 0,1 1)@2001-01-04]}'));
-- {"POINT(0 0)", "LINESTRING(0 0,1 1)", "POINT(1 1)"}
</programlisting>
			</listitem>

			<listitem xml:id="talpha_minValue">
				<indexterm significance="normal"><primary><varname>minValue</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>maxValue</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>avgValue</varname></primary></indexterm>
				<para>Return the minimum, maximum, or average value</para>
				<para><varname>minValue(torder) → base</varname></para>
				<para><varname>maxValue(torder) → base</varname></para>
				<para><varname>avgValue(tnumber) → base</varname></para>
				<para>The functions do not take into account whether the bounds are inclusive or not.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT minValue(tfloat '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
-- 1
SELECT maxValue(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
-- 5
SELECT avgValue(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
-- 2.75
</programlisting>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT minValue(ttext '{[A@2001-01-01, B@2001-01-02], [C@2001-01-03, E@2001-01-05]}');
-- A
SELECT maxValue(ttext '{[A@2001-01-01, B@2001-01-02], [C@2001-01-03, E@2001-01-05]}');
-- E
</programlisting>
			</listitem>

			<listitem xml:id="talpha_minInstant">
				<indexterm significance="normal"><primary><varname>minInstant</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>maxInstant</varname></primary></indexterm>
				<para>Return the instant with the minimum or maximum value</para>
				<para><varname>minInstant(torder) → base</varname></para>
				<para><varname>maxInstant(torder) → base</varname></para>
				<para>The function does not take into account whether the bounds are inclusive or not. If several instants have the minimum value, the first one is returned.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT minInstant(tfloat '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
-- 1@2001-01-01
SELECT maxInstant(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
-- 5@2001-01-05
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="talpha_transformations">
		<title>Transformations</title>
		<itemizedlist>
			<listitem xml:id="tnumber_shiftValue">
				<indexterm significance="normal"><primary><varname>shiftValue</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>scaleValue</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>shiftScaleValue</varname></primary></indexterm>
				<para>Shift and/or the value span of a temporal number by one or two numbers</para>
				<para><varname>shiftValue(tnumber,base) → tnumber</varname></para>
				<para><varname>scaleValue(tnumber,width) → tnumber</varname></para>
				<para><varname>shiftScaleValue(tnumber,base,base) → tnumber</varname></para>
				<para>For scaling, if the value span of the temporal value is a single value (for example, for a temporal instant), the result is the temporal value. Furthermore, the given width must be strictly greater than zero.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT shiftValue(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}', 1);
-- {2@2001-01-02, 3@2001-01-04, 2@2001-01-06}
SELECT shiftValue(tfloat '{[1@2001-01-01,2@2001-01-02],[3@2001-01-03,4@2001-01-04]}', -1);
--  {[0@2001-01-01, 1@2001-01-02], [2@2001-01-03, 3@2001-01-04]}
SELECT scaleValue(tint '1@2001-01-01', 1);
-- 1@2001-01-01
SELECT scaleValue(tfloat '{[1@2001-01-01,2@2001-01-02], [3@2001-01-03,4@2001-01-04]}', 6);
-- {[1@2001-01-01, 3@2001-01-03], [5@2001-01-05, 7@2001-01-07]}
SELECT scaleValue(tint '1@2001-01-01', -1);
-- ERROR:   The value must be strictly positive: -1
SELECT shiftScaleValue(tint '1@2001-01-01', 1, 1);
-- 2@2001-01-01
SELECT shiftScaleValue(tfloat '{[1@2001-01-01,2@2001-01-02],[3@2001-01-03,4@2001-01-04]}',
  -1, 6);
--  {[0@2001-01-01, 2@2001-01-02], [4@2001-01-03, 6@2001-01-04]}
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_stops">
				<indexterm significance="normal"><primary><varname>stops</varname></primary></indexterm>
				<para>Extract from a temporal float with linear interpolation the subsequences where the values stay within a span of a given width for at least a given duration</para>
				<para><varname>stops(tfloat,maxDist=0.0,minDuration='0 minutes') → tfloat</varname></para>
				<para>If <varname>maxDist</varname> is not given, a value 0.0 is assumed by default and thus, the function extracts the constant segments of the temporal float.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT stops(tfloat '[1@2001-01-01, 1@2001-01-02, 2@2001-01-03]');
-- {[1@2001-01-01, 1@2001-01-02)}
SELECT stops(tfloat '[1@2001-01-01, 1@2001-01-02, 2@2001-01-03]', 0.0, '2 days');
-- NULL
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="talpha_restrictions">
		<title>Restrictions</title>
		<itemizedlist>
			<listitem xml:id="talpha_atMin">
				<indexterm significance="normal"><primary><varname>atMin</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>atMax</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>minusMin</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>minusMax</varname></primary></indexterm>
				<para>Restrict to (the complement of) the minimum or maximum value</para>
				<para><varname>atMin(torder) → torder</varname></para>
				<para><varname>atMax(torder) → torder</varname></para>
				<para><varname>minusMin(torder) → torder</varname></para>
				<para><varname>minusMax(torder) → torder</varname></para>
				<para>The functions returns a NULL value if the minimum value only happens at exclusive bounds.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT atMin(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}');
-- {1@2001-01-01, 1@2001-01-05}
SELECT atMin(tint '(1@2001-01-01, 3@2001-01-03]');
-- {(1@2001-01-01, 1@2001-01-03)}
SELECT atMin(tfloat '(1@2001-01-01, 3@2001-01-03]');
-- NULL
SELECT atMin(ttext '{(AA@2001-01-01, AA@2001-01-03), (BB@2001-01-03, AA@2001-01-05]}');
-- {(AA@2001-01-01, AA@2001-01-03), [AA@2001-01-05]}
SELECT atMax(tint '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
-- {3@2001-01-05}
SELECT atMax(tfloat '(1@2001-01-01, 3@2001-01-03)');
-- NULL
SELECT atMax(tfloat '{(2@2001-01-01, 1@2001-01-03), [2@2001-01-03, 2@2001-01-05)}');
-- {[2@2001-01-03, 2@2001-01-05]}
SELECT atMax(ttext '{(AA@2001-01-01, AA@2001-01-03), (BB@2001-01-03, AA@2001-01-05]}');
-- {("BB"@2001-01-03, "BB"@2001-01-05)}
</programlisting>

				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT minusMin(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}');
-- {2@2001-01-03}
SELECT minusMin(tfloat '[1@2001-01-01, 3@2001-01-03]');
-- {(1@2001-01-01, 3@2001-01-03]}
SELECT minusMin(tfloat '(1@2001-01-01, 3@2001-01-03)');
-- {(1@2001-01-01, 3@2001-01-03)}
SELECT minusMin(tint '{[1@2001-01-01, 1@2001-01-03), (1@2001-01-03, 1@2001-01-05)}');
-- NULL
SELECT minusMax(tint '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
-- {1@2001-01-01, 2@2001-01-03}
SELECT minusMax(tfloat '[1@2001-01-01, 3@2001-01-03]');
-- {[1@2001-01-01, 3@2001-01-03)}
SELECT minusMax(tfloat '(1@2001-01-01, 3@2001-01-03)');
-- {(1@2001-01-01, 3@2001-01-03)}
SELECT minusMax(tfloat '{[2@2001-01-01, 1@2001-01-03), [2@2001-01-03, 2@2001-01-05)}');
-- {(2@2001-01-01, 1@2001-01-03)}
SELECT minusMax(tfloat '{[1@2001-01-01, 3@2001-01-03), (3@2001-01-03, 1@2001-01-05)}');
-- {[1@2001-01-01, 3@2001-01-03), (3@2001-01-03, 1@2001-01-05)}
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_atTbox">
				<indexterm significance="normal"><primary><varname>atTbox</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>minusTbox</varname></primary></indexterm>
				<para>Restrict to (the complement of) a <varname>tbox</varname></para>
				<para><varname>atTbox(tnumber,tbox) → tnumber</varname></para>
				<para><varname>minusTbox(tnumber,tbox) → tnumber</varname></para>
				<para>Cuando el cuadro delimitador tiene dimensiones tanto de valores como temporales, las funciones restringen el número temporal con respecto al valor <emphasis>y</emphasis> las extensiones temporales del cuadro.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT atTbox(tfloat '[0@2001-01-01, 3@2001-01-04)',
  tbox 'TBOXFLOAT XT((0,2),[2001-01-02, 2001-01-04])');
-- {[1@2001-01-02, 2@2001-01-03]}
</programlisting>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT minusTbox(tfloat '[1@2001-01-01, 4@2001-01-04)',
  'TBOXFLOAT XT((1,4),[2001-01-03, 2001-01-04])');
-- {[1@2001-01-01, 3@2001-01-03)}
WITH temp(temp, box) AS (
  SELECT tfloat '[1@2001-01-01, 4@2001-01-04)',
    tbox 'TBOXFLOAT XT((1,2),[2001-01-03, 2001-01-04])' )
SELECT minusValues(minusTime(temp, box::tstzspan), box::floatspan) FROM temp;
-- {[1@2001-01-01], [2@2001-01-02, 3@2001-01-03)}
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="temporal_types_bool">
		<title>Boolean Operations</title>
		<itemizedlist>
			<listitem xml:id="tbool_and">
				<indexterm significance="normal"><primary><varname>&amp;</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>|</varname></primary></indexterm>
				<para>Temporal and, temporal or</para>
				<para><varname>{boolean,tbool} {&amp;, |} {boolean,tbool} → tbool</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tbool '[true@2001-01-03, true@2001-01-05)' &amp;
  tbool '[false@2001-01-03, false@2001-01-05)';
-- [f@2001-01-03, f@2001-01-05)
SELECT tbool '[true@2001-01-03, true@2001-01-05)' &amp;
  tbool '{[false@2001-01-03, false@2001-01-04),
  [true@2001-01-04, true@2001-01-05)}';
-- {[f@2001-01-03, t@2001-01-04, t@2001-01-05)}
SELECT tbool '[true@2001-01-03, true@2001-01-05)' |
  tbool '[false@2001-01-03, false@2001-01-05)';
-- [t@2001-01-03, t@2001-01-05)
</programlisting>
			</listitem>

			<listitem xml:id="tbool_not">
				<indexterm significance="normal"><primary><varname>~</varname></primary></indexterm>
				<para>Temporal not</para>
				<para><varname>~tbool → tbool</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT ~tbool '[true@2001-01-03, true@2001-01-05)';
-- [f@2001-01-03, f@2001-01-05)
</programlisting>
			</listitem>

			<listitem xml:id="tbool_whenTrue">
				<indexterm significance="normal"><primary><varname>whenTrue</varname></primary></indexterm>
				<para>Return the time when a temporal Boolean takes the value true</para>
				<para><varname>whenTrue(tbool) → tstzspanset</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT whenTrue(tfloat '[1@2001-01-01, 4@2001-01-04, 1@2001-01-07]' #&gt; 2);
-- {(2001-01-02, 2001-01-06)}
SELECT whenTrue(tdwithin(tgeompoint '[Point(1 1)@2001-01-01, Point(4 4)@2001-01-04,
  Point(1 1)@2001-01-07]', geometry 'Point(1 1)', sqrt(2)));
-- {[2001-01-01, 2001-01-02], [2001-01-06, 2001-01-07]}
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="temporal_types_math">
		<title>Mathematical Operations</title>

		<itemizedlist>
			<listitem xml:id="tnumber_add">
				<indexterm significance="normal"><primary><varname>+</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>-</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>*</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>/</varname></primary></indexterm>
				<para>Temporal addition, subtraction, multiplication, and division</para>
				<para><varname>{number,tnumber} {+, -, *, /} {number,tnumber} → tnumber</varname></para>
				<para>The temporal division will raise an error if the denominator is ever equal to zero during the common timespan of the arguments.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[2@2001-01-01, 2@2001-01-04)' + 1;
-- [3@2001-01-01, 3@2001-01-04)
SELECT tfloat '[2@2001-01-01, 2@2001-01-04)' + tfloat '[1@2001-01-01, 4@2001-01-04)';
-- [3@2001-01-01, 6@2001-01-04)
SELECT tfloat '[1@2001-01-01, 4@2001-01-04)' +
  tfloat '{[1@2001-01-01, 2@2001-01-02), [1@2001-01-02, 2@2001-01-04)}';
-- {[2@2001-01-01, 4@2001-01-04), [3@2001-01-02, 6@2001-01-04)}
</programlisting>

				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[1@2001-01-01, 1@2001-01-04)' - tint '[2@2001-01-03, 2@2001-01-05)';
-- [-1@2001-01-03, -1@2001-01-04)
SELECT tfloat '[3@2001-01-01, 6@2001-01-04)' - tfloat '[2@2001-01-01, 2@2001-01-04)';
-- [1@2001-01-01, 4@2001-01-04)
</programlisting>

				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT tint '[1@2001-01-01, 4@2001-01-04]' * 2;
-- [2@2001-01-01, 8@2001-01-04]
SELECT tfloat '[1@2001-01-01, 4@2001-01-04)' * tfloat '[2@2001-01-01, 2@2001-01-04)';
-- [2@2001-01-01, 8@2001-01-04)
SELECT tfloat '[1@2001-01-01, 3@2001-01-03)' * '[3@2001-01-01, 1@2001-01-03)'
-- {[3@2001-01-01, 4@2001-01-02, 3@2001-01-03)}
</programlisting>

				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT 2 / tfloat '[1@2001-01-01, 3@2001-01-04)';
-- [2@2001-01-01, 0.666666666666667@2001-01-04)
SELECT tfloat '[1@2001-01-01, 5@2001-01-05)' / tfloat '[5@2001-01-01, 1@2001-01-05)';
-- {[0.2@2001-01-01, 1@2001-01-03,2001-01-03, 5@2001-01-03,2001-01-05)}
SELECT 2 / tfloat '[-1@2001-01-01, 1@2001-01-02]';
-- ERROR:  Division by zero
SELECT tfloat '[-1@2001-01-04, 1@2001-01-05]' / tfloat '[-1@2001-01-01, 1@2001-01-05]';
-- [-2@2001-01-04, 1@2001-01-05]
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_abs">
				<indexterm significance="normal"><primary><varname>abs</varname></primary></indexterm>
				<para>Return the absolute value of the temporal number</para>
				<para><varname>abs(tnumber) → tnumber</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT abs(tfloat '[1@2001-01-01, -1@2001-01-03, 1@2001-01-05]');
-- [1@2001-01-01, 0@2001-01-02, 1@2001-01-03, 0@2001-01-04, 1@2001-01-05]
SELECT abs(tint '[1@2001-01-01, -1@2001-01-03, 1@2001-01-05]');
-- [1@2001-01-01, 1@2001-01-05]
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_floor">
				<indexterm significance="normal"><primary><varname>floor</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>ceil</varname></primary></indexterm>
				<para>Round up or down to the neareast integer</para>
				<para><varname>floor(tfloat) → tfloat</varname></para>
				<para><varname>ceil(tfloat) → tfloat</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT floor(tfloat '[0.5@2001-01-01, 1.5@2001-01-02]');
-- [0@2001-01-01, 1@2001-01-02]
SELECT ceil(tfloat '[0.5@2001-01-01, 0.6@2001-01-02, 0.7@2001-01-03]');
-- [1@2001-01-01, 1@2001-01-03]
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_round">
				<indexterm significance="normal"><primary><varname>round</varname></primary></indexterm>
				<para>Round to a number of decimal places</para>
				<para><varname>round(tfloat,integer=0) → tfloat</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT round(tfloat '[0.785398163397448@2001-01-01, 2.356194490192345@2001-01-02]', 2);
-- [0.79@2001-01-01, 2.36@2001-01-02]
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_degrees">
				<indexterm significance="normal"><primary><varname>degrees</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>radians</varname></primary></indexterm>
				<para>Convert to degrees or radians</para>
				<para><varname>degrees({float,tfloat},normalize=false) → tfloat</varname></para>
				<para><varname>radians(tfloat) → tfloat</varname></para>
				<para>The additional parameter in the <varname>degrees</varname> function can be used to normalize the values between 0 and 360 degrees.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT degrees(pi() * 5);
-- 900
SELECT degrees(pi() * 5, true);
-- 180
SELECT round(degrees(tfloat '[0.785398163397448@2001-01-01, 2.356194490192345@2001-01-02]'));
-- [45@2001-01-01, 135@2001-01-02]
SELECT radians(tfloat '[45@2001-01-01, 135@2001-01-02]');
-- [0.785398163397448@2001-01-01, 2.356194490192345@2001-01-02]
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_deltaValue">
				<indexterm significance="normal"><primary><varname>deltaValue</varname></primary></indexterm>
				<para>Return the value difference between consecutive instants of the temporal number</para>
				<para><varname>deltaValue(tnumber) → tnumber</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT deltaValue(tint '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]');
-- [1@2001-01-01, -1@2001-01-02, -1@2001-01-03)
SELECT deltaValue(tfloat '{[1.5@2001-01-01, 2@2001-01-02, 1@2001-01-03],
  [2@2001-01-04, 2@2001-01-05]}');
/* Interp=Step;{[0.5@2001-01-01, -1@2001-01-02, -1@2001-01-03),
  [0@2001-01-04, 0@2001-01-05)} */
</programlisting>
			</listitem>

			<listitem xml:id="tfloat_trend">
				<indexterm significance="normal"><primary><varname>trend</varname></primary></indexterm>
				<para>Return the trend of a temporal float with linear interpolation, which states whether its value is increasing, constant, or decreasing, represented, respectively, by 1, 0, and -1.</para>
				<para><varname>trend(tfloat) → tint</varname></para>
				<para>Note that the trend is NULL for instantaneous sequences.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT trend(tfloat '[1@2001-01-01, 2@2001-01-02, 4@2001-01-03, 4@2001-01-04, 3@2001-01-05, 2@2001-01-06]');
-- [1@2001-01-01, 0@2001-01-03, -1@2001-01-04, -1@2001-01-06]
SELECT trend(tfloat '[1@2001-01-01]');
-- NULL
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_derivative">
				<indexterm significance="normal"><primary><varname>derivative</varname></primary></indexterm>
				<para>Return the derivative over time of a temporal float in units per second</para>
				<para><varname>derivative(tfloat) → tfloat</varname></para>
				<para>The temporal float must have linear interpolation. Note that this function corresponds to the <link linkend="tgeo_speed"><varname>speed</varname></link> function for temporal points.</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT derivative(tfloat '{[0@2001-01-01, 10@2001-01-02, 5@2001-01-03],
  [1@2001-01-04, 0@2001-01-05]}') * 3600 * 24;
/* Interp=Step;{[-10@2001-01-01, 5@2001-01-02, 5@2001-01-03],
  [1@2001-01-04, 1@2001-01-05]} */
SELECT derivative(tfloat 'Interp=Step;[0@2001-01-01, 10@2001-01-02, 5@2001-01-03]');
-- ERROR:  The temporal value must have linear interpolation
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_integral">
				<indexterm significance="normal"><primary><varname>integral</varname></primary></indexterm>
				<para>Return the area under the curve</para>
				<para><varname>integral(tnumber) → float</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT  integral(tint '[1@2001-01-01,2@2001-01-02]') / (24 * 3600 * 1e6);
-- 1
SELECT integral(tfloat '[1@2001-01-01,2@2001-01-02]') / (24 * 3600 * 1e6);
-- 1.5
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_twAvg">
				<indexterm significance="normal"><primary><varname>twAvg</varname></primary></indexterm>
				<para>Return the time-weighted average</para>
				<para><varname>twAvg(tnumber) → float</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT twAvg(tfloat '{[1@2001-01-01, 2@2001-01-03), [2@2001-01-04, 2@2001-01-06)}');
-- 1.75
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_ln">
				<indexterm significance="normal"><primary><varname>ln</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>log10</varname></primary></indexterm>
				<para>Return the natural logarithm and the base 10 logarithm of a temporal float</para>
				<para><varname>ln(tfloat) → tfloat</varname></para>
				<para><varname>log10(tfloat) → tfloat</varname></para>
				<para>The temporal float cannot be zero or negative</para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT ln(tfloat '{[1@2001-01-01, 10@2001-01-02, 5@2001-01-03],
  [1@2001-01-04, 1@2001-01-05]}');
/* {[0@2001-01-01, 2.302585092994046@2001-01-02, 1.6094379124341@2001-01-03], 
   [0@2001-01-04, 0@2001-01-05]} */
SELECT log10(tfloat 'Interp=Step;[-10@2001-01-01, 10@2001-01-02]');
-- ERROR:  Cannot take logarithm of zero or a negative number
</programlisting>
			</listitem>

			<listitem xml:id="tnumber_exp">
				<indexterm significance="normal"><primary><varname>exp</varname></primary></indexterm>
				<para>Return the exponential (e raised to the given power) of a temporal float</para>
				<para><varname>exp(tfloat) → tfloat</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT exp(tfloat '{[1@2001-01-01, 10@2001-01-02],
  [1@2001-01-04, 1@2001-01-05]}');
/* {[2.718281828459045@2001-01-01, 22026.465794806718@2001-01-02], 
   [2.718281828459045@2001-01-04, 2.718281828459045@2001-01-05]} */
SELECT exp(tfloat '{-10@2001-01-01, 0@2001-01-02, 10@2001-01-03}');
-- {0.000045399929762@2001-01-01, 1@2001-01-02, 22026.465794806718@2001-01-03}
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

	<sect1 xml:id="temporal_types_text">
		<title>Text Operations</title>

		<itemizedlist>
			<listitem xml:id="ttext_concat">
				<indexterm significance="normal"><primary><varname>||</varname></primary></indexterm>
				<para>Text concatenation</para>
				<para><varname>{text,ttext} || {text,ttext} → ttext</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT ttext '[AA@2001-01-01, AA@2001-01-04)' || text 'B';
-- ["AAB"@2001-01-01, "AAB"@2001-01-04)
SELECT ttext '[AA@2001-01-01, AA@2001-01-04)' || ttext '[BB@2001-01-02, BB@2001-01-05)';
-- ["AABB"@2001-01-02, "AABB"@2001-01-04)
SELECT ttext '[A@2001-01-01, B@2001-01-03, C@2001-01-04]' ||
  ttext '{[D@2001-01-01, D@2001-01-02), [E@2001-01-02, E@2001-01-04)}';
-- {["AD"@2001-01-01, "AE"@2001-01-02, "BE"@2001-01-03, "BE"@2001-01-04)}
</programlisting>
			</listitem>

			<listitem xml:id="ttext_lower">
				<indexterm significance="normal"><primary><varname>lower</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>upper</varname></primary></indexterm>
				<indexterm significance="normal"><primary><varname>initcap</varname></primary></indexterm>
				<para>Transform in lowercase, uppercase, or initcap</para>
				<para><varname>upper(ttext) → ttext</varname></para>
				<para><varname>lower(ttext) → ttext</varname></para>
				<para><varname>initcap(ttext) → ttext</varname></para>
				<programlisting language="sql" xml:space="preserve" format="linespecific">
SELECT lower(ttext '[AA@2001-01-01, bb@2001-01-02]');
-- ["aa"@2001-01-01, "bb"@2001-01-02]
SELECT upper(ttext '[AA@2001-01-01, bb@2001-01-02]');
-- ["AA"@2001-01-01, "BB"@2001-01-02]
SELECT initcap(ttext '[AA@2001-01-01, bb@2001-01-02]');
-- ["Aa"@2001-01-01, "Bb"@2001-01-02]
</programlisting>
			</listitem>
		</itemizedlist>
	</sect1>

</chapter>


