Hello.

While I looked a patch, I found that the following ECPG statement
generates uncompilable .c source.

EXEC SQL CREATE TABLE t AS stmt;

ecpgtest.c:
#line 42 "ecpgtest.pgc"

                printf("1:dbname=%s\n", dbname);
                { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, create table 
t as execute "stmt", ECPGt_EOIT, ECPGt_EORT);

This is apparently broken. The cause is that the rule ExecutStmt is
assumed to return a statement name when type is empty (or null), while
it actually returns a full statement for the CREATE TABLE AS EXECUTE
syntax.

Separating "CREATE TABLE AS EXECUTE" from ExecuteStmt would be cleaner
but I avoided to change the syntax tree. Instead the attched make
distinction of $$.type of ExecuteStmt between NULL and "" to use to
notify the returned name is name of a prepared statement or a full
statement.

I'll post the test part later.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 75a99097a988c81802d659cf8a58d74060d36409 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota....@gmail.com>
Date: Thu, 1 Jul 2021 14:56:42 +0900
Subject: [PATCH v1] Fix ECPG's CREATE TABLE AS EXECUTE

The syntax was precompiled into uncompilable .c statement.

Avoiding impact on parse tree structure, use ExecuteStmt.type to
notify whether the returned string is a statment name or a full
statement.
---
 src/interfaces/ecpg/preproc/ecpg.addons | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index b6e3412cef..820608605b 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -34,7 +34,9 @@ ECPG: stmtUpdateStmt block
 ECPG: stmtExecuteStmt block
 	{
 		check_declared_list($1.name);
-		if ($1.type == NULL || strlen($1.type) == 0)
+		if ($1.type == NULL)
+			output_statement($1.name, 1, ECPGst_normal);
+		else if (strlen($1.type) == 0)
 			output_statement($1.name, 1, ECPGst_execute);
 		else
 		{
@@ -362,14 +364,18 @@ ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
 	{
 		$$.name = $2;
 		$$.type = $3;
+		if ($$.type == NULL)
+		   $$.type = "";
 	}
 ECPG: ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block
 	{
 		$$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table"),$4,mm_strdup("as execute"),$7,$8,$9);
+		$$.type = NULL;
 	}
 ECPG: ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block
 	{
 		$$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table if not exists"),$7,mm_strdup("as execute"),$10,$11,$12);
+		$$.type = NULL;
 	}
 ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block
 	{
-- 
2.27.0

Reply via email to