greenplumn output 源码
greenplumn output 代码
文件路径:/src/interfaces/ecpg/preproc/output.c
/* src/interfaces/ecpg/preproc/output.c */
#include "postgres_fe.h"
#include "preproc_extern.h"
static void output_escaped_str(char *cmd, bool quoted);
static void output_cursor_name(char *str);
void
output_line_number(void)
{
char *line = hashline_number();
fprintf(base_yyout, "%s", line);
free(line);
}
void
output_simple_statement(char *stmt, int whenever_mode)
{
output_escaped_str(stmt, false);
if (whenever_mode)
whenever_action(whenever_mode);
output_line_number();
free(stmt);
}
/*
* store the whenever action here
*/
struct when when_error,
when_nf,
when_warn;
static void
print_action(struct when *w)
{
switch (w->code)
{
case W_SQLPRINT:
fprintf(base_yyout, "sqlprint();");
break;
case W_GOTO:
fprintf(base_yyout, "goto %s;", w->command);
break;
case W_DO:
fprintf(base_yyout, "%s;", w->command);
break;
case W_STOP:
fprintf(base_yyout, "exit (1);");
break;
case W_BREAK:
fprintf(base_yyout, "break;");
break;
case W_CONTINUE:
fprintf(base_yyout, "continue;");
break;
default:
fprintf(base_yyout, "{/* %d not implemented yet */}", w->code);
break;
}
}
void
whenever_action(int mode)
{
if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
{
output_line_number();
fprintf(base_yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
print_action(&when_nf);
}
if (when_warn.code != W_NOTHING)
{
output_line_number();
fprintf(base_yyout, "\nif (sqlca.sqlwarn[0] == 'W') ");
print_action(&when_warn);
}
if (when_error.code != W_NOTHING)
{
output_line_number();
fprintf(base_yyout, "\nif (sqlca.sqlcode < 0) ");
print_action(&when_error);
}
if ((mode & 2) == 2)
fputc('}', base_yyout);
output_line_number();
}
char *
hashline_number(void)
{
/* do not print line numbers if we are in debug mode */
if (input_filename
#ifdef YYDEBUG
&& !base_yydebug
#endif
)
{
/* "* 2" here is for escaping '\' and '"' below */
char *line = mm_alloc(strlen("\n#line %d \"%s\"\n") + sizeof(int) * CHAR_BIT * 10 / 3 + strlen(input_filename) * 2);
char *src,
*dest;
sprintf(line, "\n#line %d \"", base_yylineno);
src = input_filename;
dest = line + strlen(line);
while (*src)
{
if (*src == '\\' || *src == '"')
*dest++ = '\\';
*dest++ = *src++;
}
*dest = '\0';
strcat(dest, "\"\n");
return line;
}
return EMPTY;
}
static char *ecpg_statement_type_name[] = {
"ECPGst_normal",
"ECPGst_execute",
"ECPGst_exec_immediate",
"ECPGst_prepnormal",
"ECPGst_prepare",
"ECPGst_exec_with_exprlist"
};
void
output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
{
fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
if (st == ECPGst_prepnormal && !auto_prepare)
st = ECPGst_normal;
/*
* In following cases, stmt is CSTRING or char_variable. They must be
* output directly. - prepared_name of EXECUTE without exprlist -
* execstring of EXECUTE IMMEDIATE
*/
fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
if (st == ECPGst_execute || st == ECPGst_exec_immediate)
fprintf(base_yyout, "%s, ", stmt);
else
{
fputs("\"", base_yyout);
output_escaped_str(stmt, false);
fputs("\", ", base_yyout);
}
/* dump variables to C file */
dump_variables(argsinsert, 1);
fputs("ECPGt_EOIT, ", base_yyout);
dump_variables(argsresult, 1);
fputs("ECPGt_EORT);", base_yyout);
reset_variables();
whenever_action(whenever_mode | 2);
free(stmt);
if (connection != NULL)
free(connection);
connection = NULL;
}
void
output_prepare_statement(char *name, char *stmt)
{
fprintf(base_yyout, "{ ECPGprepare(__LINE__, %s, %d, ", connection ? connection : "NULL", questionmarks);
output_escaped_str(name, true);
fputs(", ", base_yyout);
output_escaped_str(stmt, true);
fputs(");", base_yyout);
whenever_action(2);
free(name);
if (connection != NULL)
free(connection);
connection = NULL;
}
void
output_deallocate_prepare_statement(char *name)
{
const char *con = connection ? connection : "NULL";
if (strcmp(name, "all") != 0)
{
fprintf(base_yyout, "{ ECPGdeallocate(__LINE__, %d, %s, ", compat, con);
output_escaped_str(name, true);
fputs(");", base_yyout);
}
else
fprintf(base_yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
whenever_action(2);
free(name);
if (connection != NULL)
free(connection);
connection = NULL;
}
static void
output_escaped_str(char *str, bool quoted)
{
int i = 0;
int len = 0;
if (str == NULL)
{
fputs("NULL", base_yyout);
return;
}
len = strlen(str);
if (quoted && str[0] == '"' && str[len - 1] == '"') /* do not escape quotes
* at beginning and end
* if quoted string */
{
i = 1;
len--;
fputs("\"", base_yyout);
}
/* output this char by char as we have to filter " and \n */
for (; i < len; i++)
{
if (str[i] == '"')
fputs("\\\"", base_yyout);
else if (str[i] == '\n')
fputs("\\\n", base_yyout);
else if (str[i] == '\\')
{
int j = i;
/*
* check whether this is a continuation line if it is, do not
* output anything because newlines are escaped anyway
*/
/* accept blanks after the '\' as some other compilers do too */
do
{
j++;
} while (str[j] == ' ' || str[j] == '\t');
if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
* newline */
fputs("\\\\", base_yyout);
}
else if (str[i] == '\r' && str[i + 1] == '\n')
{
fputs("\\\r\n", base_yyout);
i++;
}
else
fputc(str[i], base_yyout);
}
if (quoted && str[0] == '"' && str[len] == '"')
fputs("\"", base_yyout);
}
/*
* This is a tool function used by the output_cursor_statement function to print
* cursor name after the string such as "ECPGopen(","ECPGfetch(","ECPGclose(".
* This function filters escaped sequences such as \t, \n, \r to print cursor name cleanly
*/
static void
output_cursor_name(char *str)
{
int i = 0;
int len = 0;
if (str == NULL)
{
fputs("NULL", base_yyout);
return;
}
len = strlen(str);
fputs("\"", base_yyout);
if (str[0] == '\"' && str[len - 1] == '\"')
{
i = 1;
len--;
fputs("\\\"", base_yyout);
/* output this char by char as we have to filter " and \n */
for (; i < len; i++)
{
if (str[i] == '"')
fputs("\\\"", base_yyout);
else if (str[i] == '\n')
fputs("\\\n", base_yyout);
else if (str[i] == '\\')
{
int j = i;
/*
* check whether this is a continuation line if it is, do not
* output anything because newlines are escaped anyway
*/
/* accept blanks after the '\' as some other compilers do too */
do
{
j++;
} while (str[j] == ' ' || str[j] == '\t');
if ((str[j] != '\n') && (str[j] != '\r' || str[j + 1] != '\n')) /* not followed by a
* newline */
fputs("\\\\", base_yyout);
}
else if (str[i] == '\r' && str[i + 1] == '\n')
{
fputs("\\\r\n", base_yyout);
i++;
}
else
fputc(str[i], base_yyout);
}
fputs("\\\"", base_yyout);
}
else
fputs(str, base_yyout);
fputs("\"", base_yyout);
}
/*
* Transform the EXEC SQL DECLARE STATEMENT into ECPGdeclare function
*/
void
output_declare_statement(char *name)
{
/* connection is set in "at:" token in ecpg.trailer file */
fprintf(base_yyout, "{ ECPGdeclare(__LINE__, %s, ", connection ? connection : "NULL");
output_escaped_str(name, true);
fputs(");", base_yyout);
whenever_action(2);
free(name);
if (connection != NULL)
free(connection);
}
/*
* Transform the EXEC SQL CURSOR STATEMENT such as OPEN/FETCH/CLOSE cursor into
* ECPGopen/ECPGfetch/ECPGclose function
*/
void
output_cursor_statement(int cursor_stmt, char *cursor_name, char *prepared_name, char *stmt, int whenever_mode, enum ECPG_statement_type st)
{
switch (cursor_stmt)
{
case ECPGcst_open:
fprintf(base_yyout, "{ ECPGopen(");
output_cursor_name(cursor_name);
fprintf(base_yyout, ", ");
output_escaped_str(prepared_name, true);
fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
compat, force_indicator, connection ? connection : "NULL", questionmarks);
break;
case ECPGcst_fetch:
fprintf(base_yyout, "{ ECPGfetch(");
output_cursor_name(cursor_name);
fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
compat, force_indicator, connection ? connection : "NULL", questionmarks);
break;
case ECPGcst_close:
fprintf(base_yyout, "{ ECPGclose(");
output_cursor_name(cursor_name);
fprintf(base_yyout, ", __LINE__, %d, %d, %s, %d, ",
compat, force_indicator, connection ? connection : "NULL", questionmarks);
break;
}
if (st == ECPGst_execute || st == ECPGst_exec_immediate)
fprintf(base_yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
else
{
if (st == ECPGst_prepnormal && auto_prepare)
fputs("ECPGst_prepnormal, \"", base_yyout);
else
fputs("ECPGst_normal, \"", base_yyout);
output_escaped_str(stmt, false);
fputs("\", ", base_yyout);
}
/* dump variables to C file */
dump_variables(argsinsert, 1);
fputs("ECPGt_EOIT, ", base_yyout);
dump_variables(argsresult, 1);
fputs("ECPGt_EORT);", base_yyout);
reset_variables();
whenever_action(whenever_mode | 2);
free(cursor_name);
free(prepared_name);
free(stmt);
if (connection != NULL)
free(connection);
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦