This is an automated email from the ASF dual-hosted git repository.

maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git


The following commit(s) were added to refs/heads/main by this push:
     new 747b953ab9 Fix unrecognized node type of pg_task
747b953ab9 is described below

commit 747b953ab91cc0634bbdc31dc1ec2ed5cd31fa04
Author: roseduan <[email protected]>
AuthorDate: Tue Dec 3 10:16:19 2024 +0800

    Fix unrecognized node type of pg_task
    
    If the task executes in a function, an error 'unrecognized node type:
    742 (copyfuncs.c:7358)' will occur.
    
    This is caused by the serialize and deserialize routine is missed of
    the task statement.
    
    Discussion: https://github.com/apache/cloudberry/issues/740
---
 src/backend/nodes/copyfuncs.c      | 47 ++++++++++++++++++++++++++++++++++++++
 src/backend/nodes/equalfuncs.c     | 41 +++++++++++++++++++++++++++++++++
 src/backend/nodes/outfast.c        |  9 ++++++++
 src/backend/nodes/outfuncs.c       | 40 ++++++++++++++++++++++++++++++++
 src/backend/nodes/readfast.c       | 46 +++++++++++++++++++++++++++++++++++++
 src/test/regress/expected/task.out | 33 ++++++++++++++++++++++++++
 src/test/regress/sql/task.sql      | 22 ++++++++++++++++++
 7 files changed, 238 insertions(+)

diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index b0e2fc50f2..ed54da0526 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -5757,6 +5757,43 @@ _copyDistributedBy(const DistributedBy *from)
        return newnode;
 }
 
+static CreateTaskStmt *
+_copyCreateTaskStmt(const CreateTaskStmt *from)
+{
+       CreateTaskStmt *newnode = makeNode(CreateTaskStmt);
+
+       COPY_STRING_FIELD(taskname);
+       COPY_STRING_FIELD(schedule);
+       COPY_STRING_FIELD(sql);
+       COPY_NODE_FIELD(options);
+       COPY_SCALAR_FIELD(if_not_exists);
+
+       return newnode;
+}
+
+static AlterTaskStmt *
+_copyAlterTaskStmt(const AlterTaskStmt *from)
+{
+       AlterTaskStmt *newnode = makeNode(AlterTaskStmt);
+
+       COPY_STRING_FIELD(taskname);
+       COPY_NODE_FIELD(options);
+       COPY_SCALAR_FIELD(missing_ok);
+
+       return newnode;
+}
+
+static DropTaskStmt *
+_copyDropTaskStmt(const DropTaskStmt *from)
+{
+       DropTaskStmt *newnode = makeNode(DropTaskStmt);
+
+       COPY_STRING_FIELD(taskname);
+       COPY_SCALAR_FIELD(missing_ok);
+
+       return newnode;
+}
+
 static CreatePolicyStmt *
 _copyCreatePolicyStmt(const CreatePolicyStmt *from)
 {
@@ -7324,6 +7361,16 @@ copyObjectImpl(const void *from)
                        retval = _copyDistributedBy(from);
                        break;
 
+               case T_CreateTaskStmt:
+                       retval = _copyCreateTaskStmt(from);
+                       break;
+               case T_AlterTaskStmt:
+                       retval = _copyAlterTaskStmt(from);
+                       break;
+               case T_DropTaskStmt:
+                       retval = _copyDropTaskStmt(from);
+                       break;
+
                        /*
                         * MISCELLANEOUS NODES
                         */
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 8af8252fef..1617dd3896 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -3484,6 +3484,37 @@ _equalAlterDirectoryTableStmt(const 
AlterDirectoryTableStmt *a, const AlterDirec
        return true;
 }
 
+static bool
+_equalCreateTaskStmt(const CreateTaskStmt *a, const CreateTaskStmt *b)
+{
+       COMPARE_STRING_FIELD(taskname);
+       COMPARE_STRING_FIELD(schedule);
+       COMPARE_STRING_FIELD(sql);
+       COMPARE_NODE_FIELD(options);
+       COMPARE_SCALAR_FIELD(if_not_exists);
+
+       return true;
+}
+
+static bool
+_equalAlterTaskStmt(const AlterTaskStmt *a, const AlterTaskStmt *b)
+{
+       COMPARE_STRING_FIELD(taskname);
+       COMPARE_NODE_FIELD(options);
+       COMPARE_SCALAR_FIELD(missing_ok);
+
+       return true;
+}
+
+static bool
+_equalDropTaskStmt(const DropTaskStmt *a, const DropTaskStmt *b)
+{
+       COMPARE_STRING_FIELD(taskname);
+       COMPARE_SCALAR_FIELD(missing_ok);
+
+       return true;
+}
+
 /*
  * Stuff from pg_list.h
  */
@@ -4440,6 +4471,16 @@ equal(const void *a, const void *b)
                        retval = _equalAlterDirectoryTableStmt(a, b);
                        break;
 
+               case T_CreateTaskStmt:
+                       retval = _equalCreateTaskStmt(a, b);
+                       break;
+               case T_AlterTaskStmt:
+                       retval = _equalAlterTaskStmt(a, b);
+                       break;
+               case T_DropTaskStmt:
+                       retval = _equalDropTaskStmt(a, b);
+                       break;
+
                default:
                        elog(ERROR, "unrecognized node type: %d",
                                 (int) nodeTag(a));
diff --git a/src/backend/nodes/outfast.c b/src/backend/nodes/outfast.c
index e7baefe5d7..d7ba7f2d78 100644
--- a/src/backend/nodes/outfast.c
+++ b/src/backend/nodes/outfast.c
@@ -1898,6 +1898,15 @@ _outNode(StringInfo str, void *obj)
                        case T_AlterDirectoryTableStmt:
                                _outAlterDirectoryTableStmt(str, obj);
                                break;
+                       case T_CreateTaskStmt:
+                               _outCreateTaskStmt(str, obj);
+                               break;
+                       case T_AlterTaskStmt:
+                               _outAlterTaskStmt(str, obj);
+                               break;
+                       case T_DropTaskStmt:
+                               _outDropTaskStmt(str, obj);
+                               break;
                        case T_EphemeralNamedRelationInfo:
                                _outEphemeralNamedRelationInfo(str, obj);
                                break;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 3521410160..c5f7423b2e 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -4045,6 +4045,37 @@ _outAlterDirectoryTableStmt(StringInfo str, const 
AlterDirectoryTableStmt *node)
        WRITE_BOOL_FIELD(unsettag);
 }
 
+static void
+_outCreateTaskStmt(StringInfo str, const CreateTaskStmt *node)
+{
+       WRITE_NODE_TYPE("CREATETASKSTMT");
+
+       WRITE_STRING_FIELD(taskname);
+       WRITE_STRING_FIELD(schedule);
+       WRITE_STRING_FIELD(sql);
+       WRITE_NODE_FIELD(options);
+       WRITE_BOOL_FIELD(if_not_exists);
+}
+
+static void
+_outAlterTaskStmt(StringInfo str, const AlterTaskStmt *node)
+{
+       WRITE_NODE_TYPE("ALTERTASKSTMT");
+
+       WRITE_STRING_FIELD(taskname);
+       WRITE_NODE_FIELD(options);
+       WRITE_BOOL_FIELD(missing_ok);
+}
+
+static void
+_outDropTaskStmt(StringInfo str, const DropTaskStmt *node)
+{
+       WRITE_NODE_TYPE("DROPTASKSTMT");
+
+       WRITE_STRING_FIELD(taskname);
+       WRITE_BOOL_FIELD(missing_ok);
+}
+
 #include "outfuncs_common.c"
 #ifndef COMPILING_BINARY_FUNCS
 /*
@@ -5202,6 +5233,15 @@ outNode(StringInfo str, const void *obj)
                        case T_AlterDirectoryTableStmt:
                                _outAlterDirectoryTableStmt(str, obj);
                                break;
+                       case T_CreateTaskStmt:
+                               _outCreateTaskStmt(str, obj);
+                               break;
+                       case T_AlterTaskStmt:
+                               _outAlterTaskStmt(str, obj);
+                               break;
+                       case T_DropTaskStmt:
+                               _outDropTaskStmt(str, obj);
+                               break;
                        default:
 
                                /*
diff --git a/src/backend/nodes/readfast.c b/src/backend/nodes/readfast.c
index 71c9207f9f..792caf466e 100644
--- a/src/backend/nodes/readfast.c
+++ b/src/backend/nodes/readfast.c
@@ -1774,6 +1774,43 @@ _readAlterDirectoryTableStmt(void)
        READ_DONE();
 }
 
+static CreateTaskStmt *
+_readCreateTaskStmt(void)
+{
+       READ_LOCALS(CreateTaskStmt);
+
+       READ_STRING_FIELD(taskname);
+       READ_STRING_FIELD(schedule);
+       READ_STRING_FIELD(sql);
+       READ_NODE_FIELD(options);
+       READ_BOOL_FIELD(if_not_exists);
+
+       READ_DONE();
+}
+
+static AlterTaskStmt *
+_readAlterTaskStmt(void)
+{
+       READ_LOCALS(AlterTaskStmt);
+
+       READ_STRING_FIELD(taskname);
+       READ_NODE_FIELD(options);
+       READ_BOOL_FIELD(missing_ok);
+
+       READ_DONE();
+}
+
+static DropTaskStmt *
+_readDropTaskStmt(void)
+{
+       READ_LOCALS(DropTaskStmt);
+
+       READ_STRING_FIELD(taskname);
+       READ_BOOL_FIELD(missing_ok);
+
+       READ_DONE();
+}
+
 static EphemeralNamedRelationInfo *
 _readEphemeralNamedRelationInfo(void)
 {
@@ -2858,6 +2895,15 @@ readNodeBinary(void)
                        case T_AlterDirectoryTableStmt:
                                return_value = _readAlterDirectoryTableStmt();
                                break;
+                       case T_CreateTaskStmt:
+                               return_value = _readCreateTaskStmt();
+                               break;
+                       case T_AlterTaskStmt:
+                               return_value = _readAlterTaskStmt();
+                               break;
+                       case T_DropTaskStmt:
+                               return_value = _readDropTaskStmt();
+                               break;
                        default:
                                return_value = NULL; /* keep the compiler 
silent */
                                elog(ERROR, "could not deserialize unrecognized 
node type: %d",
diff --git a/src/test/regress/expected/task.out 
b/src/test/regress/expected/task.out
index bb9a72ac50..2f052fdad1 100644
--- a/src/test/regress/expected/task.out
+++ b/src/test/regress/expected/task.out
@@ -73,6 +73,39 @@ create task valid_task_1 schedule '1 second' as 'select 1';
 create task valid_task_2 schedule ' 30 sEcOnDs ' as 'select 1';
 create task valid_task_3 schedule '59 seconds' as 'select 1';
 create task valid_task_4 schedule '17  seconds ' as 'select 1';
+-- task in function
+DO $$
+BEGIN
+       create task fn_task schedule '5 * * * * ' as 'select 1';
+END $$;
+select jobname from pg_task where jobname = 'fn_task';
+ jobname 
+---------
+ fn_task
+(1 row)
+
+DO $$
+BEGIN
+       alter task fn_task schedule '6 * * * *';
+END $$;
+select schedule from pg_task where jobname = 'fn_task';
+ schedule  
+-----------
+ 6 * * * *
+(1 row)
+
+DO $$
+DECLARE
+       jn text;
+BEGIN
+       SELECT jobname from pg_task where jobname = 'fn_task' into jn;
+       EXECUTE FORMAT('DROP TASK %I', jn);
+END $$;
+select jobname from pg_task where jobname = 'fn_task';
+ jobname 
+---------
+(0 rows)
+
 -- clean up
 drop database task_dbno;
 drop user task_cron;
diff --git a/src/test/regress/sql/task.sql b/src/test/regress/sql/task.sql
index 217b265daf..bf12909c76 100644
--- a/src/test/regress/sql/task.sql
+++ b/src/test/regress/sql/task.sql
@@ -54,6 +54,28 @@ create task valid_task_2 schedule ' 30 sEcOnDs ' as 'select 
1';
 create task valid_task_3 schedule '59 seconds' as 'select 1';
 create task valid_task_4 schedule '17  seconds ' as 'select 1';
 
+-- task in function
+DO $$
+BEGIN
+       create task fn_task schedule '5 * * * * ' as 'select 1';
+END $$;
+select jobname from pg_task where jobname = 'fn_task';
+
+DO $$
+BEGIN
+       alter task fn_task schedule '6 * * * *';
+END $$;
+select schedule from pg_task where jobname = 'fn_task';
+
+DO $$
+DECLARE
+       jn text;
+BEGIN
+       SELECT jobname from pg_task where jobname = 'fn_task' into jn;
+       EXECUTE FORMAT('DROP TASK %I', jn);
+END $$;
+select jobname from pg_task where jobname = 'fn_task';
+
 -- clean up
 drop database task_dbno;
 drop user task_cron;


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

Reply via email to