*** I:\pgdev\pgsql\src\backend\catalog\pg_proc.c.orig 2007-09-03 02:39:14.000000000 +0200 --- I:\pgdev\pgsql\src\backend\catalog\pg_proc.c 2007-11-03 12:29:13.832352000 +0100 *************** *** 33,45 **** #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/syscache.h" ! Datum fmgr_internal_validator(PG_FUNCTION_ARGS); Datum fmgr_c_validator(PG_FUNCTION_ARGS); Datum fmgr_sql_validator(PG_FUNCTION_ARGS); static void sql_function_parse_error_callback(void *arg); static int match_prosrc_to_query(const char *prosrc, const char *queryText, int cursorpos); static bool match_prosrc_to_literal(const char *prosrc, const char *literal, --- 33,47 ---- #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/syscache.h" ! #include "parser/parse_callback.h" ! #include "parser/parse_expr.h" Datum fmgr_internal_validator(PG_FUNCTION_ARGS); Datum fmgr_c_validator(PG_FUNCTION_ARGS); Datum fmgr_sql_validator(PG_FUNCTION_ARGS); static void sql_function_parse_error_callback(void *arg); + static void sql_parser_callback_handler(ParserCallbackContextArgs *args); static int match_prosrc_to_query(const char *prosrc, const char *queryText, int cursorpos); static bool match_prosrc_to_literal(const char *prosrc, const char *literal, *************** *** 531,536 **** --- 533,539 ---- Datum tmp; char *prosrc; ErrorContextCallback sqlerrcontext; + ParserCallbackContext sqlcallbackcontext; bool haspolyarg; int i; *************** *** 586,591 **** --- 589,601 ---- sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; + /* attaching parser callback handler*/ + sqlcallbackcontext.context = T_ParsingFunctionBody; + sqlcallbackcontext.ctxarg = tuple; + sqlcallbackcontext.callback = sql_parser_callback_handler; + sqlcallbackcontext.previous = parser_callback_context_stack; + parser_callback_context_stack = &sqlcallbackcontext; + /* * We can't do full prechecking of the function definition if there * are any polymorphic input types, because actual datatypes of *************** *** 607,612 **** --- 617,623 ---- querytree_list = pg_parse_query(prosrc); error_context_stack = sqlerrcontext.previous; + parser_callback_context_stack = sqlcallbackcontext.previous; } ReleaseSysCache(tuple); *************** *** 614,619 **** --- 625,660 ---- PG_RETURN_VOID(); } + /* handler for parser callback. this function is used to handle + * 1. SQL-language reference parameters by name + */ + static void + sql_parser_callback_handler(ParserCallbackContextArgs *args) + { + HeapTuple tuple; + int numargs; + Oid *argtypes; + char **argnames; + char *argmodes; + + ParserCallbackContext *currentctx = parser_callback_context_stack; + if(currentctx->context == T_ParsingFunctionBody) + { + switch(args->action) + { + case A_ResolveAmbigColumnRef: + tuple = (HeapTuple)currentctx->ctxarg; + numargs = get_func_arg_info(tuple, + &argtypes, &argnames, &argmodes); + /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + * @ TODO: + * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + */ + break; + } + } + } + /* * Error context callback for handling errors in SQL function definitions */ *** I:\pgdev\pgsql\src\backend\parser\parse_callback.c.orig 1970-01-01 01:00:00.000000000 +0100 --- I:\pgdev\pgsql\src\backend\parser\parse_callback.c 2007-11-03 12:31:36.948142400 +0100 *************** *** 0 **** --- 1,34 ---- + /*------------------------------------------------------------------------- + * + * parse_callback.c + * Mechanisme to create callbacks from inside the parser + * + * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/parser/parse_callback.c $ + * + *------------------------------------------------------------------------- + */ + + #include "postgres.h" + #include "parser/parse_node.h" + #include "parser/parse_callback.h" + + /* global parser callback handler context stack */ + ParserCallbackContext *parser_callback_context_stack = NULL; + + /* This function can be called from various positions within + * the parser to handle custom/language-specific actions. + * For example: The handling of referenced function argument names. + */ + void parser_do_callback(ParserCallbackContextArgs *args) + { + ParserCallbackContext *ctx; + for (ctx = parser_callback_context_stack; + ctx != NULL; + ctx = ctx->previous) + (*ctx->callback) (args); + } \ No newline at end of file *** I:\pgdev\pgsql\src\backend\parser\parse_expr.c.orig 2007-06-24 00:12:51.000000000 +0200 --- I:\pgdev\pgsql\src\backend\parser\parse_expr.c 2007-11-03 11:42:27.737385600 +0100 *************** *** 31,36 **** --- 31,37 ---- #include "parser/parse_relation.h" #include "parser/parse_target.h" #include "parser/parse_type.h" + #include "parser/parse_callback.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/xml.h" *************** *** 410,423 **** --- 411,442 ---- */ if (refnameRangeTblEntry(pstate, NULL, name, &levels_up) != NULL) + { node = transformWholeRowRef(pstate, NULL, name, cref->location); + } else + { + /* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + * @ TODO: + * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + */ + /* we make a final attempt to resolve this column ref */ + ParserCallbackContextArgs args; + args.pstate = pstate; + args.input = (Node *)cref; + args.action = A_ResolveAmbigColumnRef; + parser_do_callback(&args); + } + + if(node == NULL) + { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" does not exist", name), parser_errposition(pstate, cref->location))); + } } break; } *** I:\pgdev\pgsql\src\include\parser\parse_callback.h.orig 1970-01-01 01:00:00.000000000 +0100 --- I:\pgdev\pgsql\src\include\parser\parse_callback.h 2007-11-03 12:31:07.405662400 +0100 *************** *** 0 **** --- 1,55 ---- + /*------------------------------------------------------------------------- + * + * parse_callback.h + * Definitions for the parser callback mechanism + * + * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/parser/parse_callback.h $ + * + *------------------------------------------------------------------------- + */ + + /* provides information to callback handler function to determine + * in wat context whis callback is called. + * PS: this list can be extended as needed. + */ + typedef enum ParserCallbackContextTag + { + T_ParsingFunctionBody = 10 + } ParserCallbackContextTag; + + /* Action types that is passed to the callback handler. + * PS: this list can be extended as needed. + */ + typedef enum ParserCallbackAction + { + A_ResolveAmbigColumnRef = 10 + } ParserCallbackAction; + + /* Support for handling callbacks from within the parser to + * external functions. + */ + typedef struct ParserCallbackContext + { + ParserCallbackContextTag context; /* indicates the current context */ + struct ParserCallbackContext *previous; /* previous callback context */ + void (*callback) (ParserCallbackContextArgs); /* callback handler function */ + void *ctxarg; /* context argument set when a handler is setup */ + } ParserCallbackContext; + + /* Support for passing data from within parser to callback handler function */ + typedef struct ParserCallbackContextArgs + { + ParseState *pstate; /* parser state */ + Node *input; /* current Node that is being processed in parser */ + Node *result; /* the result of callback handler function */ + ParserCallbackAction action; /* What to do in callback handler function */ + } ParserCallbackContextArgs; + + /* global callback handler */ + extern PGDLLIMPORT ParserCallbackContext *parser_callback_context_stack; + extern void parser_do_callback(ParserCallbackContextArgs *args);