GitHub user vovik0134 added a comment to the discussion: [Ideas] Description of 
backward-incompatible changes between Greenplum 6 and Cloudberry in the 
documentation.

We also identified backward-incompatible changes in syntactic constructs.

## Syntax changes and removed constructs

### Explicit `ROW()` is required in `UPDATE` statements with row constructors

Starting with PostgreSQL kernel version 10, when updating a single column via a 
`ROW` constructor, the `ROW` keyword must be specified explicitly.

In Greenplum 6, the following query works without errors:

```sql
CREATE TABLE example (value text);

INSERT INTO example (value) VALUES ('a');

-- this query
UPDATE example SET (value) = (value || '_updated');
```

In Cloudberry, the same query fails with an error:

```sql
CREATE TABLE example (value text);

INSERT INTO example (value) VALUES ('a');

-- this query
UPDATE example SET (value) = (value || '_updated');
ERROR:  source for a multiple-column UPDATE item must be a sub-SELECT or ROW() 
expression
```

**How to detect**

Check the application codebase for uses of a `ROW` constructor for a single 
column.

**How to fix**

Modify the problematic queries so that they either do not use a `ROW` 
constructor, for example, `UPDATE ... SET col = expr`, or explicitly specify 
the `ROW` keyword: `UPDATE ... SET (col) = ROW(expr)`.

### Statement-level triggers are not supported

Unlike Greenplum 6, Cloudberry does not support statement-level triggers.

The following queries work correctly in Greenplum 6:

```sql
CREATE TABLE example (
    id bigserial,
    value text
) DISTRIBUTED BY (id);

CREATE OR REPLACE FUNCTION example_trigger_func()
RETURNS TRIGGER AS $$
BEGIN
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER example_trigger
    AFTER INSERT OR UPDATE ON example
    FOR EACH STATEMENT
    EXECUTE PROCEDURE example_trigger_func();
```

But they do not work in Cloudberry:

```sql
CREATE TABLE example (
    id bigserial,
    value text
) DISTRIBUTED BY (id);

CREATE OR REPLACE FUNCTION example_trigger_func()
RETURNS TRIGGER AS $$
BEGIN
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER example_trigger
    AFTER INSERT OR UPDATE ON example
    FOR EACH STATEMENT
    EXECUTE PROCEDURE example_trigger_func();

ERROR:  Triggers for statements are not yet supported
```

**How to detect**

All statement-level triggers can be found with the following query:

```sql
SELECT n.nspname, c.relname, tgname
FROM pg_trigger t
    JOIN pg_class c ON t.tgrelid = c.oid
    JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE tgtype & 1 = 0 AND NOT tgisinternal;
```

**How to fix**

Stop using statement-level triggers: move the logic to the application side or 
use row-level triggers.

### Functions with `EXECUTE ON` must return sets (`SETOF`)

In Cloudberry, functions with the `EXECUTE ON ALL SEGMENTS` / `COORDINATOR` / 
`INITPLAN` attributes must now return `SETOF`.

A valid example for Greenplum 6:

```sql
CREATE OR REPLACE FUNCTION example_func()
RETURNS integer
AS $$
BEGIN
    RETURN 42;
END;
$$ LANGUAGE plpgsql
EXECUTE ON ALL SEGMENTS;
```

This stops working in Cloudberry:

```sql
CREATE OR REPLACE FUNCTION example_func()
RETURNS integer
AS $$
BEGIN
    RETURN 42;
END;
$$ LANGUAGE plpgsql
EXECUTE ON ALL SEGMENTS;

ERROR:  EXECUTE ON ALL SEGMENTS is only supported for set-returning functions
```

**How to detect**

Functions with the `EXECUTE ON ALL SEGMENTS` / `COORDINATOR` / `INITPLAN` 
attributes that do not return `SETOF` can be found with the following query:

```sql
SELECT n.nspname, p.proname
FROM pg_proc p
    JOIN pg_language l ON l.oid = p.prolang
    JOIN pg_type t ON t.oid = p.prorettype
    JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE NOT proretset
    AND proexeclocation IN ('s', 'm', 'i')
    AND l.lanname NOT IN ('internal')
    AND t.typname NOT IN ('record');
```

**How to fix**

Recreate the problematic functions with `RETURNS SETOF ...` and `RETURN NEXT`.

### Support for postfix operators has been removed

Starting with PostgreSQL kernel version 14, support for postfix operators has 
been removed, both system-defined and user-defined ones.

In Greenplum 6, the following query works without errors:

```sql
SELECT 5! AS factorial;
 factorial
-----------
       120
```

In Cloudberry, the same query fails with an error:

```sql
SELECT 5! AS factorial;
ERROR:  syntax error at or near "AS"
LINE 1: SELECT 5! AS factorial;
```

**How to detect**

In Greenplum 6, there is only one system postfix operator: `!`. However, 
user-defined operators may also exist. The full list of postfix operators can 
be obtained with the following query:

```sql
SELECT o.oid, n.nspname, o.oprname, o.oid < 16384 AS is_system
FROM pg_operator o
    JOIN pg_namespace n ON o.oprnamespace = n.oid
WHERE o.oprright = 0;
```

**How to fix**

* Replace uses of the `!` operator with an explicit call to the 
`factorial(...)` function.
* Replace user-defined postfix operators with prefix operators or with explicit 
calls to the corresponding functions.

GitHub link: 
https://github.com/apache/cloudberry/discussions/1816#discussioncomment-17260286

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to