Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format specifier for integer variables in format() for EXECUTE?

CREATE OR REPLACE FUNCTION getParentLtree(parent_id bigint, tbl_name varchar) 
  RETURNS ltree AS
$BODY$
DECLARE
   parent_ltree ltree;
BEGIN
-- This works fine:
-- select into parent_ltree l_tree from tbl1 where id = parent_id;

EXECUTE format('select into parent_ltree l_tree from %I
                where id = %I', tbl_name,parent_id);

RETURN parent_ltree;
END;
$BODY$ LANGUAGE plpgsql;

There are 2 issues in above function:

  1. parent_id is integer but it is replaced with quotes? What is the correct format specifier for int variables?
  2. select into does not work with EXECUTE? How can I make above commented query to use table name passed?
like image 831
RAFIQ Avatar asked Mar 26 '14 09:03

RAFIQ


People also ask

What is the use of %s format specifier explain with example?

The format specifier is used during input and output. It is a way to tell the compiler what type of data is in a variable during taking input using scanf() or printing using printf(). Some examples are %c, %d, %f, etc.

What is %U in printf?

Unsigned Integer Format Specifier %u The %u format specifier is implemented for fetching values from the address of a variable having an unsigned decimal integer stored in the memory. It is used within the printf() function for printing the unsigned integer variable.

What is format specifier in C?

Format Specifiers in C are just a type of string or operator which are mainly used while taking the input from the user and while outputting something on the console. Their motive is to specify the Data type of the input or output to the compiler. By data type, we mean integer, string, float etc.


1 Answers

This would be shorter, faster and safer:

CREATE OR REPLACE FUNCTION get_parent_ltree(parent_id bigint, tbl_name regclass
                                          , OUT parent_ltree ltree)
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format('SELECT l_tree FROM %s WHERE id = $1', tbl_name)
   INTO  parent_ltree
   USING parent_id;
END
$func$;

Why?

Most importantly, use the USING clause of EXECUTE for parameter values. Don't convert them to text, concatenate and interpret them back. That would be slower and error-prone.

Normally you would use the %I specifier with format() for identifiers like the table name. For existing tables, a regclass object-identifier type may be even better. See:

  • Table name as a PostgreSQL function parameter

The OUT parameter makes it simpler. Performance is the same.

Don't use unquoted CaMeL case identifiers like getParentLtree in Postgres. Details in the manual.

like image 59
Erwin Brandstetter Avatar answered Nov 16 '22 06:11

Erwin Brandstetter