Thread: Character escape in "CREATE FUNCTION ..."

Character escape in "CREATE FUNCTION ..."

From
Shilong Stanley Yao
Date:
Dear All,
I am trying to write a function in Postgresql, which takes 2 floats and
returns a box.  But seems the nested single-quote in the AS clause
prevent $1 and $2 from being expanded.  Besides writing a C function
instead of a SQL one, is there any way to solve this problem?

Thanks a lot.
-Stan

CREATE OR REPLACE FUNCTION func_radec_to_box(float, float) RETURNS box
         AS 'SELECT box \'(($1, $2), (1.3, 1.4))\''
         LANGUAGE 'sql'
         WITH (ISCACHABLE);


Error message:
psql:func_radec_to_box.sql:4: ERROR:  Bad box external representation
'(($1, $2), (1.3, 1.4))'


Re: Character escape in "CREATE FUNCTION ..."

From
Richard Huxton
Date:
On Monday 15 March 2004 18:38, Shilong Stanley Yao wrote:
> Dear All,
> I am trying to write a function in Postgresql, which takes 2 floats and
> returns a box.  But seems the nested single-quote in the AS clause
> prevent $1 and $2 from being expanded.  Besides writing a C function
> instead of a SQL one, is there any way to solve this problem?

> CREATE OR REPLACE FUNCTION func_radec_to_box(float, float) RETURNS box
>          AS 'SELECT box \'(($1, $2), (1.3, 1.4))\''
>          LANGUAGE 'sql'
>          WITH (ISCACHABLE);

If the box constructor is supposed to take a string, try something like:

SELECT box \'((\' || $1 || \'...etc

That is to say - use string concatenation

--
  Richard Huxton
  Archonet Ltd

Re: Character escape in "CREATE FUNCTION ..."

From
Bruno Wolff III
Date:
On Mon, Mar 15, 2004 at 11:38:05 -0700,
  Shilong Stanley Yao <yao@noao.edu> wrote:
> Dear All,
> I am trying to write a function in Postgresql, which takes 2 floats and
> returns a box.  But seems the nested single-quote in the AS clause
> prevent $1 and $2 from being expanded.  Besides writing a C function
> instead of a SQL one, is there any way to solve this problem?

I believe you want to concatenate $1 and $2 with the constants parts
of the string rather than to embed them in the string.

The cube type in contrib/cube already has functions for making a cube
from float8 numbers without converting to text inbetween. Depending
on what you want this might be another approach for you.

>
> Thanks a lot.
> -Stan
>
> CREATE OR REPLACE FUNCTION func_radec_to_box(float, float) RETURNS box
>         AS 'SELECT box \'(($1, $2), (1.3, 1.4))\''
>         LANGUAGE 'sql'
>         WITH (ISCACHABLE);
>
>
> Error message:
> psql:func_radec_to_box.sql:4: ERROR:  Bad box external representation
> '(($1, $2), (1.3, 1.4))'
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
>               http://www.postgresql.org/docs/faqs/FAQ.html

Re: Character escape in "CREATE FUNCTION ..."

From
Tom Lane
Date:
Shilong Stanley Yao <yao@noao.edu> writes:
> I am trying to write a function in Postgresql, which takes 2 floats and
> returns a box.  But seems the nested single-quote in the AS clause
> prevent $1 and $2 from being expanded.  Besides writing a C function
> instead of a SQL one, is there any way to solve this problem?

> CREATE OR REPLACE FUNCTION func_radec_to_box(float, float) RETURNS box
>          AS 'SELECT box \'(($1, $2), (1.3, 1.4))\''
>          LANGUAGE 'sql'
>          WITH (ISCACHABLE);

This is never going to work because you are trying to use the
typed-literal syntax with something that you don't actually want to
be a literal constant.  You need to think in terms of a function, not
a literal.  In this case I think what you want is the box-from-two-points
constructor function, together with the point-from-two-floats constructor:

    ... AS 'SELECT box(point($1, $2), point(1.3, 1.4))'

If you had a mind to, you could write the constant point as a literal:

    ... AS 'SELECT box(point($1, $2), point \'1.3, 1.4\')'

but you can't write the variable point as a literal.

            regards, tom lane

Re: Character escape in "CREATE FUNCTION ..."

From
Shilong Stanley Yao
Date:
Tom Lane wrote:
> Shilong Stanley Yao <yao@noao.edu> writes:
>
>>I am trying to write a function in Postgresql, which takes 2 floats and
>>returns a box.  But seems the nested single-quote in the AS clause
>>prevent $1 and $2 from being expanded.  Besides writing a C function
>>instead of a SQL one, is there any way to solve this problem?
>
>
>>CREATE OR REPLACE FUNCTION func_radec_to_box(float, float) RETURNS box
>>         AS 'SELECT box \'(($1, $2), (1.3, 1.4))\''
>>         LANGUAGE 'sql'
>>         WITH (ISCACHABLE);
>
>
> This is never going to work because you are trying to use the
> typed-literal syntax with something that you don't actually want to
> be a literal constant.  You need to think in terms of a function, not
> a literal.  In this case I think what you want is the box-from-two-points
> constructor function, together with the point-from-two-floats constructor:
>
>     ... AS 'SELECT box(point($1, $2), point(1.3, 1.4))'
>
> If you had a mind to, you could write the constant point as a literal:
>
>     ... AS 'SELECT box(point($1, $2), point \'1.3, 1.4\')'
>
> but you can't write the variable point as a literal.
>
>             regards, tom lane
Thank you very much for this nice solution.  It worked very well!
BTW, a spatial query involving RTREE indexes showes that SQL function is
  much slower than C function, which is within the expectation.
Thanks everyone of the previous responses for your help too!
Stan