Class ComplexScalar

  • All Implemented Interfaces:
    SQLData

    @SQLAction(requires={"complex assertHasValues","complex relationals"},
               install={"CREATE OPERATOR CLASS javatest.complex_ops  DEFAULT FOR TYPE javatest.complex USING btree AS  OPERATOR 1 javatest.<  ,  OPERATOR 2 javatest.<= ,  OPERATOR 3 javatest.=  ,  OPERATOR 4 javatest.>= ,  OPERATOR 5 javatest.>  ,  FUNCTION 1 javatest.cmpMagnitude(javatest.complex,javatest.complex)","SELECT javatest.assertHasValues( CAST(\'(1,2)\' AS javatest.complex), 1, 2)","SELECT javatest.assertHasValues( 2.0 + CAST(\'(1,2)\' AS javatest.complex) + 3.0, 6, 2)","SELECT CASE WHEN  \'(1,2)\'::javatest.complex < \'(2,2)\'::javatest.complex AND  \'(2,2)\'::javatest.complex > \'(1,2)\'::javatest.complex AND  \'(1,2)\'::javatest.complex <= \'(2,2)\'::javatest.complex THEN javatest.logmessage(\'INFO\', \'ComplexScalar operators ok\') ELSE javatest.logmessage(\'WARNING\', \'ComplexScalar operators ng\') END"},
               remove="DROP OPERATOR FAMILY javatest.complex_ops USING btree")
    @BaseUDT(schema="javatest",
             name="complex",
             internalLength=16,
             alignment=DOUBLE)
    public class ComplexScalar
    extends Object
    implements SQLData
    Complex (re and im parts are doubles) implemented in Java as a scalar UDT.

    The SQLAction here demonstrates a requires tag ("complex relationals"} that has multiple providers, something not allowed prior to PL/Java 1.6.1. It is more succinct to require one tag and have each of the relational operators 'provide' it than to have to define and require several different tags to accomplish the same thing.

    The operator class created here is not actively used for anything (the examples will not break if it is removed), but the minMagnitude example aggregate does specify a sortOperator, which PostgreSQL will not exploit in query optimization without finding it as a member of a btree operator class.

    Note that CREATE OPERATOR CLASS implicitly creates an operator family as well (unless one is explicitly specified), so the correct remove action to clean everything up is DROP OPERATOR FAMILY (which takes care of dropping the class).

    • Method Detail

      • logAndReturn

        @Operator(name="javatest.<<",
                  right="javatest.complex")
        @Function(schema="javatest",
                  name="logcomplex",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static ComplexScalar logAndReturn​(ComplexScalar cpl)
        Return the same 'complex' passed in, logging its contents at level INFO.

        Also create an unnecessary << operator for this, with an equally unnecessary explicit operand type, simply as a regression test of issue #330.

        Parameters:
        cpl - any instance of this UDT
        Returns:
        the same instance passed in
      • assertHasValues

        @Function(schema="javatest",
                  provides="complex assertHasValues",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static void assertHasValues​(ComplexScalar cpl,
                                           double re,
                                           double im)
                                    throws SQLException
        Assert a 'complex' has given re and im values, to test that its representation in Java corresponds to what PostgreSQL sees.
        Parameters:
        cpl - an instance of this UDT
        re - the 'real' value it should have
        im - the 'imaginary' value it should have
        Throws:
        SQLException - if the values do not match
      • add

        @Operator(name={"javatest","+"},
                  commutator=".self.")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static ComplexScalar add​(ComplexScalar a,
                                        ComplexScalar b)
        Add two instances of ComplexScalar.
      • add

        @Operator(name={"javatest","+"},commutator=".twin.") @Operator(name={"javatest","+"},synthetic=".twin.")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static ComplexScalar add​(ComplexScalar a,
                                        double b)
        Add a ComplexScalar and a real (supplied as a double).
      • magnitudeLT

        @Operator(name="javatest.<",commutator="javatest.>",negator="javatest.>=",provides="complex relationals") @Operator(name="javatest.<=",synthetic="javatest.magnitudeLE",provides="complex relationals") @Operator(name="javatest.>=",synthetic="javatest.magnitudeGE",commutator="javatest.<=",provides="complex relationals") @Operator(name="javatest.>",synthetic="javatest.magnitudeGT",negator="javatest.<=",provides="complex relationals")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static boolean magnitudeLT​(ComplexScalar a,
                                          ComplexScalar b)
        True if the left argument is smaller than the right in magnitude (Euclidean distance from the origin).
      • componentsEQ

        @Operator(name="javatest.=",commutator=".self.",negator="javatest.<>",provides="complex relationals") @Operator(name="javatest.<>",synthetic="javatest.componentsNE",commutator=".self.",provides="complex relationals")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static boolean componentsEQ​(ComplexScalar a,
                                           ComplexScalar b)
        True if the left argument and the right are componentwise equal.
      • eqToReal

        @Operator(name="javatest.=",commutator=".twin.",negator="javatest.<>",provides="complex:double relationals") @Operator(name="javatest.=",synthetic=".twin.",negator="javatest.<>",provides="complex:double relationals") @Operator(name="javatest.<>",synthetic="javatest.neToReal",commutator=".twin.",provides="complex:double relationals") @Operator(name="javatest.<>",synthetic=".twin.",provides="complex:double relationals")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static boolean eqToReal​(ComplexScalar a,
                                       double b)
        True if the complex argument is real-valued and equal to the real argument.

        From one equality method on (complex,double) can be synthesized all four cross-type operators, = and <> for that pair of types and their TWIN commutators. One of the <> twins does need to specify what its synthetic function should be named.

      • minMagnitude

        @Aggregate(sortOperator="javatest.<")
        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL)
        public static ComplexScalar minMagnitude​(ComplexScalar a,
                                                 ComplexScalar b)
        As an ordinary function, returns the lesser in magnitude of two arguments; as a simple aggregate, returns the least in magnitude over its aggregated arguments.

        As an aggregate, this is a simple example where this method serves as the accumulate function, the state (a here) has the same type as the argument (here b), there is no finish function, and the final value of the state is the result.

        An optimization is available in case there is an index on the aggregated values based on the < operator above; in that case, the first value found in a scan of that index is the aggregate result. That is indicated here by naming the < operator as sortOperator.

      • cmpMagnitude

        @Function(schema="javatest",
                  effects=IMMUTABLE,
                  onNullInput=RETURNS_NULL,
                  provides="complex relationals")
        public static int cmpMagnitude​(ComplexScalar a,
                                       ComplexScalar b)
        An integer-returning comparison function by complex magnitude, usable to complete an example btree operator class.