📄 gram.y
字号:
raise_params : raise_params raise_param { if ($1.nused == $1.nalloc) { $1.nalloc *= 2; $1.dtnums = repalloc($1.dtnums, sizeof(int) * $1.nalloc); } $1.dtnums[$1.nused++] = $2; $$.nalloc = $1.nalloc; $$.nused = $1.nused; $$.dtnums = $1.dtnums; } | raise_param { $$.nalloc = 1; $$.nused = 1; $$.dtnums = palloc(sizeof(int) * $$.nalloc); $$.dtnums[0] = $1; } ;raise_param : ',' T_VARIABLE { $$ = yylval.var->varno; } | ',' T_RECFIELD { $$ = yylval.recfield->rfno; } | ',' T_TGARGV { $$ = yylval.trigarg->dno; } ;loop_body : proc_sect K_END K_LOOP ';' { $$ = $1; } ;stmt_execsql : execsql_start lno { PLpgSQL_stmt_execsql *new; new = malloc(sizeof(PLpgSQL_stmt_execsql)); new->cmd_type = PLPGSQL_STMT_EXECSQL; new->lineno = $2; new->sqlstmt = read_sqlstmt(';', ";", $1); $$ = (PLpgSQL_stmt *)new; } ;execsql_start : T_WORD { $$ = strdup(yytext); } | T_ERROR { $$ = strdup(yytext); } ;expr_until_semi : { $$ = plpgsql_read_expression(';', ";"); } ;expr_until_then : { $$ = plpgsql_read_expression(K_THEN, "THEN"); } ;expr_until_loop : { $$ = plpgsql_read_expression(K_LOOP, "LOOP"); } ;opt_label : { plpgsql_ns_push(NULL); $$ = NULL; } | '<' '<' opt_lblname '>' '>' { plpgsql_ns_push($3); $$ = $3; } ;opt_exitlabel : { $$ = NULL; } | T_LABEL { $$ = strdup(yytext); } ;opt_exitcond : ';' { $$ = NULL; } | K_WHEN expr_until_semi { $$ = $2; } ;opt_lblname : T_WORD { $$ = strdup(yytext); } ;lno : { plpgsql_error_lineno = yylineno; $$ = yylineno; } ;%%#ifndef YYBISON#include "pl_scan.c" /* BSD yacc wants it here */#endifPLpgSQL_expr *plpgsql_read_expression (int until, char *s){ return read_sqlstmt(until, s, "SELECT ");}static PLpgSQL_expr *read_sqlstmt (int until, char *s, char *sqlstart){ int tok; int lno; PLpgSQL_dstring ds; int nparams = 0; int params[1024]; char buf[32]; PLpgSQL_expr *expr; lno = yylineno; plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, sqlstart); while((tok = yylex()) != until) { if (tok == ';') break; if (plpgsql_SpaceScanned) { plpgsql_dstring_append(&ds, " "); } switch (tok) { case T_VARIABLE: params[nparams] = yylval.var->varno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_RECFIELD: params[nparams] = yylval.recfield->rfno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_TGARGV: params[nparams] = yylval.trigarg->dno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; default: if (tok == 0) { plpgsql_error_lineno = lno; plpgsql_comperrinfo(); elog(ERROR, "missing %s at end of SQL statement", s); } plpgsql_dstring_append(&ds, yytext); break; } } expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1); expr->dtype = PLPGSQL_DTYPE_EXPR; expr->query = strdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) { expr->params[nparams] = params[nparams]; } plpgsql_dstring_free(&ds); return expr;}static PLpgSQL_stmt *make_select_stmt(){ int tok; int lno; PLpgSQL_dstring ds; int nparams = 0; int params[1024]; char buf[32]; PLpgSQL_expr *expr; PLpgSQL_row *row = NULL; PLpgSQL_rec *rec = NULL; PLpgSQL_stmt_select *select; int have_nexttok = 0; lno = yylineno; plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, "SELECT "); while((tok = yylex()) != K_INTO) { if (tok == ';') { PLpgSQL_stmt_execsql *execsql; expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1); expr->dtype = PLPGSQL_DTYPE_EXPR; expr->query = strdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) { expr->params[nparams] = params[nparams]; } plpgsql_dstring_free(&ds); execsql = malloc(sizeof(PLpgSQL_stmt_execsql)); execsql->cmd_type = PLPGSQL_STMT_EXECSQL; execsql->sqlstmt = expr; return (PLpgSQL_stmt *)execsql; } if (plpgsql_SpaceScanned) { plpgsql_dstring_append(&ds, " "); } switch (tok) { case T_VARIABLE: params[nparams] = yylval.var->varno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_RECFIELD: params[nparams] = yylval.recfield->rfno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_TGARGV: params[nparams] = yylval.trigarg->dno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; default: if (tok == 0) { plpgsql_error_lineno = yylineno; plpgsql_comperrinfo(); elog(ERROR, "unexpected end of file"); } plpgsql_dstring_append(&ds, yytext); break; } } tok = yylex(); switch (tok) { case T_ROW: row = yylval.row; break; case T_RECORD: rec = yylval.rec; break; case T_VARIABLE: case T_RECFIELD: { PLpgSQL_var *var; PLpgSQL_recfield *recfield; int nfields = 1; char *fieldnames[1024]; int varnos[1024]; switch (tok) { case T_VARIABLE: var = yylval.var; fieldnames[0] = strdup(yytext); varnos[0] = var->varno; break; case T_RECFIELD: recfield = yylval.recfield; fieldnames[0] = strdup(yytext); varnos[0] = recfield->rfno; break; } while ((tok = yylex()) == ',') { tok = yylex(); switch(tok) { case T_VARIABLE: var = yylval.var; fieldnames[nfields] = strdup(yytext); varnos[nfields++] = var->varno; break; case T_RECFIELD: recfield = yylval.recfield; fieldnames[0] = strdup(yytext); varnos[0] = recfield->rfno; break; default: elog(ERROR, "plpgsql: %s is not a variable or record field", yytext); } } row = malloc(sizeof(PLpgSQL_row)); row->dtype = PLPGSQL_DTYPE_ROW; row->refname = strdup("*internal*"); row->lineno = yylineno; row->rowtypeclass = InvalidOid; row->nfields = nfields; row->fieldnames = malloc(sizeof(char *) * nfields); row->varnos = malloc(sizeof(int) * nfields); while (--nfields >= 0) { row->fieldnames[nfields] = fieldnames[nfields]; row->varnos[nfields] = varnos[nfields]; } plpgsql_adddatum((PLpgSQL_datum *)row); have_nexttok = 1; } break; default: { if (plpgsql_SpaceScanned) { plpgsql_dstring_append(&ds, " "); } plpgsql_dstring_append(&ds, yytext); while(1) { tok = yylex(); if (tok == ';') { PLpgSQL_stmt_execsql *execsql; expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - 1); expr->dtype = PLPGSQL_DTYPE_EXPR; expr->query = strdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) { expr->params[nparams] = params[nparams]; } plpgsql_dstring_free(&ds); execsql = malloc(sizeof(PLpgSQL_stmt_execsql)); execsql->cmd_type = PLPGSQL_STMT_EXECSQL; execsql->sqlstmt = expr; return (PLpgSQL_stmt *)execsql; } if (plpgsql_SpaceScanned) { plpgsql_dstring_append(&ds, " "); } switch (tok) { case T_VARIABLE: params[nparams] = yylval.var->varno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_RECFIELD: params[nparams] = yylval.recfield->rfno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_TGARGV: params[nparams] = yylval.trigarg->dno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; default: if (tok == 0) { plpgsql_error_lineno = yylineno; plpgsql_comperrinfo(); elog(ERROR, "unexpected end of file"); } plpgsql_dstring_append(&ds, yytext); break; } } } } /************************************************************ * Eat up the rest of the statement after the target fields ************************************************************/ while(1) { if (!have_nexttok) { tok = yylex(); } have_nexttok = 0; if (tok == ';') { break; } if (plpgsql_SpaceScanned) { plpgsql_dstring_append(&ds, " "); } switch (tok) { case T_VARIABLE: params[nparams] = yylval.var->varno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_RECFIELD: params[nparams] = yylval.recfield->rfno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; case T_TGARGV: params[nparams] = yylval.trigarg->dno; sprintf(buf, "$%d", ++nparams); plpgsql_dstring_append(&ds, buf); break; default: if (tok == 0) { plpgsql_error_lineno = yylineno; plpgsql_comperrinfo(); elog(ERROR, "unexpected end of file"); } plpgsql_dstring_append(&ds, yytext); break; } } expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (nparams - 1)); expr->dtype = PLPGSQL_DTYPE_EXPR; expr->query = strdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) { expr->params[nparams] = params[nparams]; } plpgsql_dstring_free(&ds); select = malloc(sizeof(PLpgSQL_stmt_select)); memset(select, 0, sizeof(PLpgSQL_stmt_select)); select->cmd_type = PLPGSQL_STMT_SELECT; select->rec = rec; select->row = row; select->query = expr; return (PLpgSQL_stmt *)select;}static PLpgSQL_expr *make_tupret_expr(PLpgSQL_row *row){ PLpgSQL_dstring ds; PLpgSQL_expr *expr; int i; char buf[16]; expr = malloc(sizeof(PLpgSQL_expr) + sizeof(int) * (row->nfields - 1)); expr->dtype = PLPGSQL_DTYPE_EXPR; plpgsql_dstring_init(&ds); plpgsql_dstring_append(&ds, "SELECT "); for (i = 0; i < row->nfields; i++) { sprintf(buf, "%s$%d", (i > 0) ? "," : "", i + 1); plpgsql_dstring_append(&ds, buf); expr->params[i] = row->varnos[i]; } expr->query = strdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->plan_argtypes = NULL; expr->nparams = row->nfields; plpgsql_dstring_free(&ds); return expr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -