mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:43:04 +01:00
Support for PSQL functions (only the DSQL part so far). Still work in progress.
This commit is contained in:
parent
cf9a6ff9f7
commit
1f3694c903
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,8 @@
|
||||
#define DSQL_DDL_NODES_H
|
||||
|
||||
#include "../jrd/common.h"
|
||||
#include "../dsql/node.h"
|
||||
#include "../dsql/make_proto.h"
|
||||
#include "../dsql/Nodes.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/TriState.h"
|
||||
@ -145,24 +147,58 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class CreateAlterFunctionNode : public DdlNode
|
||||
class CreateAlterFunctionNode;
|
||||
|
||||
|
||||
class FunctionNode : public DdlNode, public BlockNode
|
||||
{
|
||||
public:
|
||||
explicit FunctionNode(MemoryPool& p, const Firebird::string& sqlText)
|
||||
: DdlNode(p, sqlText)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void genReturn();
|
||||
virtual dsql_nod* resolveVariable(const dsql_str* varName);
|
||||
|
||||
protected:
|
||||
virtual CreateAlterFunctionNode* getCreateAlterNode() = 0;
|
||||
};
|
||||
|
||||
|
||||
class CreateAlterFunctionNode : public FunctionNode
|
||||
{
|
||||
public:
|
||||
explicit CreateAlterFunctionNode(MemoryPool& pool, const Firebird::string& sqlText,
|
||||
const Firebird::MetaName& aName)
|
||||
: DdlNode(pool, sqlText),
|
||||
: FunctionNode(pool, sqlText),
|
||||
name(pool, aName),
|
||||
returnType(NULL, NULL),
|
||||
create(true),
|
||||
alter(false),
|
||||
external(NULL),
|
||||
invariant(false),
|
||||
parameters(pool),
|
||||
returnType(NULL, NULL),
|
||||
variables(pool),
|
||||
outputVariables(pool),
|
||||
localDeclList(NULL),
|
||||
body(NULL),
|
||||
source(pool),
|
||||
compiled(false),
|
||||
invalid(false),
|
||||
package(pool),
|
||||
privateScope(false),
|
||||
source(pool)
|
||||
packageOwner(pool),
|
||||
privateScope(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual CreateAlterFunctionNode* getCreateAlterNode()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
||||
virtual void execute(thread_db* tdbb, jrd_tra* transaction);
|
||||
@ -172,21 +208,30 @@ protected:
|
||||
|
||||
private:
|
||||
void executeCreate(thread_db* tdbb, jrd_tra* transaction);
|
||||
bool executeAlter(thread_db* tdbb, jrd_tra* transaction);
|
||||
bool executeAlter(thread_db* tdbb, jrd_tra* transaction, bool secondPass, bool runTriggers);
|
||||
|
||||
void storeArgument(thread_db* tdbb, jrd_tra* transaction,
|
||||
unsigned pos, const TypeClause& parameter, dsql_nod* legacyDefault);
|
||||
unsigned pos, const ParameterClause& parameter);
|
||||
void compile(thread_db* tdbb, jrd_tra* transaction);
|
||||
|
||||
public:
|
||||
Firebird::MetaName name;
|
||||
TypeClause returnType;
|
||||
bool create;
|
||||
bool alter;
|
||||
ExternalClause* external;
|
||||
bool invariant;
|
||||
Firebird::Array<ParameterClause> parameters;
|
||||
Firebird::MetaName package;
|
||||
bool privateScope;
|
||||
TypeClause returnType;
|
||||
Firebird::Array<dsql_nod*> variables;
|
||||
Firebird::Array<dsql_nod*> outputVariables;
|
||||
Firebird::string source;
|
||||
dsql_nod* localDeclList;
|
||||
dsql_nod* body;
|
||||
bool compiled;
|
||||
bool invalid;
|
||||
Firebird::MetaName package;
|
||||
Firebird::string packageOwner;
|
||||
bool privateScope;
|
||||
};
|
||||
|
||||
|
||||
@ -202,10 +247,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static void dropArguments(thread_db* tdbb, jrd_tra* transaction,
|
||||
const Firebird::MetaName& functionName, const Firebird::MetaName& packageName);
|
||||
|
||||
public:
|
||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
||||
virtual void execute(thread_db* tdbb, jrd_tra* transaction);
|
||||
|
||||
protected:
|
||||
virtual DdlNode* internalDsqlPass();
|
||||
|
||||
public:
|
||||
Firebird::MetaName name;
|
||||
bool silent;
|
||||
@ -213,6 +265,37 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class RecreateFunctionNode : public FunctionNode
|
||||
{
|
||||
public:
|
||||
explicit RecreateFunctionNode(MemoryPool& p, const Firebird::string& sqlText,
|
||||
CreateAlterFunctionNode* aCreateNode)
|
||||
: FunctionNode(p, sqlText),
|
||||
createNode(aCreateNode),
|
||||
dropNode(p, sqlText, createNode->name)
|
||||
{
|
||||
dropNode.silent = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual CreateAlterFunctionNode* getCreateAlterNode()
|
||||
{
|
||||
return createNode;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
||||
virtual void execute(thread_db* tdbb, jrd_tra* transaction);
|
||||
|
||||
protected:
|
||||
virtual DdlNode* internalDsqlPass();
|
||||
|
||||
private:
|
||||
CreateAlterFunctionNode* createNode;
|
||||
DropFunctionNode dropNode;
|
||||
};
|
||||
|
||||
|
||||
class CreateAlterProcedureNode;
|
||||
|
||||
|
||||
|
@ -92,6 +92,8 @@ protected:
|
||||
DdlTriggerWhen when, int action, const Firebird::MetaName& objectName);
|
||||
void putType(const TypeClause& type, bool useSubType);
|
||||
void resetContextStack();
|
||||
Firebird::MetaName storeGlobalField(thread_db* tdbb, jrd_tra* transaction,
|
||||
const TypeClause& parameter);
|
||||
|
||||
protected:
|
||||
virtual DdlNode* internalDsqlPass()
|
||||
|
@ -954,7 +954,7 @@ SuspendNode* SuspendNode::internalDsqlPass()
|
||||
{
|
||||
DsqlCompiledStatement* statement = dsqlScratch->getStatement();
|
||||
|
||||
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_TRIGGER) // triggers only
|
||||
if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_PROCEDURE))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
// Token unknown
|
||||
@ -1027,4 +1027,56 @@ jrd_nod* SuspendNode::execute(thread_db* /*tdbb*/, jrd_req* request)
|
||||
}
|
||||
|
||||
|
||||
//--------------------
|
||||
|
||||
|
||||
ReturnNode* ReturnNode::internalDsqlPass()
|
||||
{
|
||||
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
|
||||
|
||||
if (!(dsqlScratch->flags & DsqlCompilerScratch::FLAG_FUNCTION))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
// Token unknown
|
||||
Arg::Gds(isc_token_err) <<
|
||||
Arg::Gds(isc_random) << Arg::Str("RETURN"));
|
||||
}
|
||||
|
||||
if (dsqlScratch->flags & DsqlCompilerScratch::FLAG_IN_AUTO_TRANS_BLOCK) // autonomous transaction
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-901) <<
|
||||
Arg::Gds(isc_dsql_unsupported_in_auto_trans) << Arg::Str("RETURN"));
|
||||
}
|
||||
|
||||
ReturnNode* node = FB_NEW(getPool()) ReturnNode(getPool());
|
||||
node->dsqlScratch = dsqlScratch;
|
||||
node->blockNode = statement->blockNode;
|
||||
node->value = PASS1_node(dsqlScratch, value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
void ReturnNode::print(string& text, Array<dsql_nod*>& /*nodes*/) const
|
||||
{
|
||||
text = "ReturnNode";
|
||||
}
|
||||
|
||||
|
||||
void ReturnNode::genBlr()
|
||||
{
|
||||
DsqlCompiledStatement* const statement = dsqlScratch->getStatement();
|
||||
|
||||
statement->append_uchar(blr_assignment);
|
||||
GEN_expr(dsqlScratch, value);
|
||||
statement->append_uchar(blr_variable);
|
||||
statement->append_ushort(0);
|
||||
|
||||
blockNode->genReturn();
|
||||
|
||||
statement->append_uchar(blr_leave);
|
||||
statement->append_uchar(0);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Jrd
|
||||
|
@ -256,6 +256,27 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ReturnNode : public DsqlOnlyStmtNode
|
||||
{
|
||||
public:
|
||||
explicit ReturnNode(MemoryPool& pool, dsql_nod* val = NULL)
|
||||
: DsqlOnlyStmtNode(pool), value(val)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ReturnNode* internalDsqlPass();
|
||||
|
||||
public:
|
||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
||||
virtual void genBlr();
|
||||
|
||||
public:
|
||||
BlockNode* blockNode;
|
||||
dsql_nod* value;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // DSQL_STMT_NODES_H
|
||||
|
@ -377,35 +377,6 @@ void DDL_generate(DsqlCompilerScratch* dsqlScratch, dsql_nod* node)
|
||||
bool DDL_ids(const DsqlCompilerScratch* scratch)
|
||||
{
|
||||
return !scratch->getStatement()->ddlNode;
|
||||
/*
|
||||
const dsql_nod* ddl_node = request->getStatement()->ddlNode;
|
||||
|
||||
if (!ddl_node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ddl_node->nod_type)
|
||||
{
|
||||
case nod_def_constraint:
|
||||
case nod_def_computed:
|
||||
case nod_def_view:
|
||||
case nod_redef_view:
|
||||
case nod_mod_view:
|
||||
case nod_replace_view:
|
||||
case nod_def_trigger:
|
||||
case nod_redef_trigger:
|
||||
case nod_mod_trigger:
|
||||
case nod_replace_trigger:
|
||||
case nod_def_procedure:
|
||||
case nod_redef_procedure:
|
||||
case nod_mod_procedure:
|
||||
case nod_replace_procedure:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -4514,6 +4485,10 @@ static void put_user_grant(DsqlCompilerScratch* dsqlScratch, const dsql_nod* use
|
||||
statement->append_cstring(isc_dyn_grant_proc, name->str_data);
|
||||
break;
|
||||
|
||||
case nod_func_obj:
|
||||
statement->append_cstring(isc_dyn_grant_func, name->str_data);
|
||||
break;
|
||||
|
||||
case nod_trig_obj:
|
||||
statement->append_cstring(isc_dyn_grant_trig, name->str_data);
|
||||
break;
|
||||
@ -4585,6 +4560,8 @@ static void modify_privilege(DsqlCompilerScratch* dsqlScratch,
|
||||
const dsql_str* name = (dsql_str*) table->nod_arg[0];
|
||||
if (table->nod_type == nod_procedure_name)
|
||||
statement->append_cstring(isc_dyn_prc_name, name->str_data);
|
||||
else if (table->nod_type == nod_function_name)
|
||||
statement->append_cstring(isc_dyn_fun_name, name->str_data);
|
||||
else if (table->nod_type == nod_package_name)
|
||||
statement->append_cstring(isc_dyn_pkg_name, name->str_data);
|
||||
else
|
||||
@ -5346,7 +5323,10 @@ void DDL_put_local_variable( DsqlCompilerScratch* dsqlScratch, dsql_var* variabl
|
||||
statement->append_ushort(variable->var_variable_number);
|
||||
}
|
||||
|
||||
statement->put_debug_variable(variable->var_variable_number, variable->var_name);
|
||||
if (variable->var_name[0])
|
||||
{
|
||||
statement->put_debug_variable(variable->var_variable_number, variable->var_name);
|
||||
}
|
||||
|
||||
++dsqlScratch->hiddenVarsNumber;
|
||||
}
|
||||
|
@ -325,8 +325,6 @@ class dsql_var : public pool_alloc_rpt<SCHAR, dsql_type_var>
|
||||
{
|
||||
public:
|
||||
dsql_fld* var_field; // Field on which variable is based
|
||||
//USHORT var_flags; // Reserved
|
||||
//dsql_var_type var_type; // Too cumbersome to compile the right data type.
|
||||
int var_type; // Input, output or local var.
|
||||
USHORT var_msg_number; // Message number containing variable
|
||||
USHORT var_msg_item; // Item number in message
|
||||
@ -563,6 +561,7 @@ public:
|
||||
static const unsigned FLAG_BLOCK = 0x20;
|
||||
static const unsigned FLAG_RECURSIVE_CTE = 0x40;
|
||||
static const unsigned FLAG_UPDATE_OR_INSERT = 0x80;
|
||||
static const unsigned FLAG_FUNCTION = 0x100;
|
||||
|
||||
public:
|
||||
explicit DsqlCompilerScratch(MemoryPool& p, dsql_dbb* aDbb, jrd_tra* aTransaction,
|
||||
@ -760,15 +759,6 @@ public:
|
||||
dsql_msg* blb_segment_msg; // Segment message
|
||||
};
|
||||
|
||||
//! Transaction block
|
||||
/* UNUSED
|
||||
class dsql_tra : public pool_alloc<dsql_type_tra>
|
||||
{
|
||||
public:
|
||||
dsql_tra* tra_next; // Next open transaction
|
||||
};
|
||||
*/
|
||||
|
||||
//! Implicit (NATURAL and USING) joins
|
||||
class ImplicitJoin : public pool_alloc<dsql_type_imp_join>
|
||||
{
|
||||
|
@ -165,6 +165,7 @@ static const TOK tokens[] =
|
||||
{DESC, "DESC", 1, false}, // Alias of DESCENDING
|
||||
{DESC, "DESCENDING", 1, false},
|
||||
{KW_DESCRIPTOR, "DESCRIPTOR", 2, true},
|
||||
{DETERMINISTIC, "DETERMINISTIC", 2, false},
|
||||
{KW_DIFFERENCE, "DIFFERENCE", 2, true},
|
||||
{DISCONNECT, "DISCONNECT", 2, false},
|
||||
{DISTINCT, "DISTINCT", 1, false},
|
||||
@ -325,6 +326,7 @@ static const TOK tokens[] =
|
||||
{RESTART, "RESTART", 2, true},
|
||||
{RESTRICT, "RESTRICT", 1, true},
|
||||
{RETAIN, "RETAIN", 1, false},
|
||||
{RETURN, "RETURN", 1, false},
|
||||
{RETURNING, "RETURNING", 2, true},
|
||||
{RETURNING_VALUES, "RETURNING_VALUES", 1, false},
|
||||
{RETURNS, "RETURNS", 1, false},
|
||||
|
@ -337,7 +337,9 @@ enum nod_t
|
||||
nod_package_obj,
|
||||
nod_window,
|
||||
nod_mod_field_null_flag,
|
||||
nod_continue
|
||||
nod_continue,
|
||||
nod_func_obj,
|
||||
nod_function_name
|
||||
};
|
||||
|
||||
/* enumerations of the arguments to a node, offsets
|
||||
|
@ -569,7 +569,8 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%token <legacyNode> ACOSH
|
||||
%token <legacyNode> ASINH
|
||||
%token <legacyNode> ATANH
|
||||
|
||||
%token <legacyNode> RETURN
|
||||
%token <legacyNode> DETERMINISTIC
|
||||
|
||||
// precedence declarations for expression evaluation
|
||||
|
||||
@ -663,7 +664,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <legacyNode> decimal_keyword declare declare_clause
|
||||
%type <legacyNode> decode_pairs def_computed default_par_opt default_value delete delete_positioned
|
||||
%type <legacyNode> delete_rule delete_searched delimiter_opt derived_column_list derived_table
|
||||
%type <legacyNode> distinct_clause distinct_predicate domain_clause domain_constraint
|
||||
%type <legacyNode> deterministic_opt distinct_clause distinct_predicate domain_clause domain_constraint
|
||||
%type <legacyNode> domain_constraint_clause domain_constraint_def domain_constraint_list
|
||||
%type <legacyNode> domain_default domain_default_opt domain_or_non_array_type
|
||||
%type <legacyNode> domain_or_non_array_type_name domain_type drop drop_behaviour
|
||||
@ -675,7 +676,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <legacyNode> exec_function exec_into exec_procedure exec_sql exec_stmt_inputs
|
||||
%type <legacyNode> exec_stmt_option exec_stmt_options exec_stmt_options_list exists_predicate
|
||||
%type <legacyNode> ext_datasrc ext_privs ext_pwd ext_role ext_tran ext_user extra_indices_opt
|
||||
%type <legacyNode> extract_expression
|
||||
%type <legacyNode> extract_expression execute_privilege
|
||||
%type <legacyStr> end_trigger entry_op external_file
|
||||
|
||||
%type <legacyNode> fetch_cursor fetch_opt fetch_scroll_opt file1 file_clause file_desc file_desc1
|
||||
@ -731,7 +732,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <legacyNode> plan_expression plan_item plan_item_list plan_type
|
||||
%type <legacyNode> post_event prec_scale predicate primary_constraint privilege
|
||||
%type <legacyNode> privilege_list privileges proc_block proc_inputs proc_outputs_opt
|
||||
%type <legacyNode> proc_privileges proc_statement proc_statements
|
||||
%type <legacyNode> proc_statement proc_statements
|
||||
%type <legacyStr> passwd_clause passwd_opt
|
||||
%type <int32Val> pos_short_integer precision_opt
|
||||
|
||||
@ -751,7 +752,7 @@ inline void check_copy_incr(char*& to, const char ch, const char* const string)
|
||||
%type <legacyNode> sec_shadow_files segment_clause_io segment_length_io select select_expr
|
||||
%type <legacyNode> select_expr_body select_item select_items select_list set set_generator
|
||||
%type <legacyNode> set_savepoint set_statistics set_transaction shadow_clause
|
||||
%type <legacyNode> similar_predicate simple_case
|
||||
%type <legacyNode> similar_predicate simple_case simple_UDF_name
|
||||
%type <legacyNode> simple_column_name simple_package_name simple_proc_name simple_proc_statement simple_table_name
|
||||
%type <legacyNode> simple_type simple_when_clause singleton_select singular_predicate skip_clause
|
||||
%type <legacyNode> snap_shot some starting_predicate statement stmt_start_column
|
||||
@ -860,11 +861,17 @@ statement : alter
|
||||
|
||||
grant : GRANT privileges ON table_noise simple_table_name
|
||||
TO non_role_grantee_list grant_option granted_by
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count, $2, $5, make_list($7), $8, $9); }
|
||||
| GRANT proc_privileges ON PROCEDURE simple_proc_name
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count,
|
||||
$2, $5, make_list($7), $8, $9); }
|
||||
| GRANT execute_privilege ON PROCEDURE simple_proc_name
|
||||
TO non_role_grantee_list grant_option granted_by
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count, $2, $5, make_list($7), $8, $9); }
|
||||
| GRANT proc_privileges ON PACKAGE simple_package_name
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count,
|
||||
$2, $5, make_list($7), $8, $9); }
|
||||
| GRANT execute_privilege ON FUNCTION simple_UDF_name
|
||||
TO non_role_grantee_list grant_option granted_by
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count,
|
||||
$2, $5, make_list($7), $8, $9); }
|
||||
| GRANT execute_privilege ON PACKAGE simple_package_name
|
||||
TO non_role_grantee_list grant_option granted_by
|
||||
{ $$ = make_node (nod_grant, (int) e_grant_count, $2, $5, make_list($7), $8, $9); }
|
||||
| GRANT role_name_list TO role_grantee_list role_admin_option granted_by
|
||||
@ -890,7 +897,7 @@ privilege_list : privilege
|
||||
{ $$ = make_node (nod_list, (int) 2, $1, $3); }
|
||||
;
|
||||
|
||||
proc_privileges : EXECUTE
|
||||
execute_privilege : EXECUTE
|
||||
{ $$ = make_list (make_node (nod_execute, (int) 0, NULL)); }
|
||||
;
|
||||
|
||||
@ -942,16 +949,27 @@ simple_proc_name
|
||||
{ $$ = make_node(nod_procedure_name, (int) 1, $1); }
|
||||
;
|
||||
|
||||
simple_UDF_name
|
||||
: symbol_UDF_name
|
||||
{ $$ = make_node(nod_function_name, (int) 1, $1); }
|
||||
;
|
||||
|
||||
|
||||
// REVOKE statement
|
||||
|
||||
revoke : REVOKE rev_grant_option privileges ON table_noise simple_table_name
|
||||
FROM non_role_grantee_list granted_by
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count, $3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_grant_option proc_privileges ON PROCEDURE simple_proc_name
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count,
|
||||
$3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_grant_option execute_privilege ON PROCEDURE simple_proc_name
|
||||
FROM non_role_grantee_list granted_by
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count, $3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_grant_option proc_privileges ON PACKAGE simple_package_name
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count,
|
||||
$3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_grant_option execute_privilege ON FUNCTION simple_UDF_name
|
||||
FROM non_role_grantee_list granted_by
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count,
|
||||
$3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_grant_option execute_privilege ON PACKAGE simple_package_name
|
||||
FROM non_role_grantee_list granted_by
|
||||
{ $$ = make_node (nod_revoke, (int) e_grant_count, $3, $6, make_list($8), $2, $9); }
|
||||
| REVOKE rev_admin_option role_name_list FROM role_grantee_list granted_by
|
||||
@ -990,6 +1008,8 @@ grantee_list : grantee
|
||||
grantee
|
||||
: PROCEDURE symbol_procedure_name
|
||||
{ $$ = make_node (nod_proc_obj, (int) 1, $2); }
|
||||
| FUNCTION symbol_UDF_name
|
||||
{ $$ = make_node (nod_func_obj, (int) 1, $2); }
|
||||
| PACKAGE symbol_package_name
|
||||
{ $$ = make_node (nod_package_obj, (int) 1, $2); }
|
||||
| TRIGGER symbol_trigger_name
|
||||
@ -1189,6 +1209,8 @@ recreate : RECREATE recreate_clause
|
||||
recreate_clause
|
||||
: PROCEDURE procedure_clause
|
||||
{ $$ = makeClassNode(FB_NEW(getPool()) RecreateProcedureNode(getPool(), compilingText, $2)); }
|
||||
| FUNCTION function_clause
|
||||
{ $$ = makeClassNode(FB_NEW(getPool()) RecreateFunctionNode(getPool(), compilingText, $2)); }
|
||||
| TABLE rtable_clause
|
||||
{ $$ = $2; }
|
||||
| GLOBAL TEMPORARY TABLE gtt_recreate_clause
|
||||
@ -1909,7 +1931,14 @@ default_par_opt : DEFAULT begin_trigger default_value end_default
|
||||
// FUNCTION
|
||||
|
||||
function_clause
|
||||
: function_clause_start external_clause external_body_clause_opt
|
||||
: function_clause_start AS begin_string local_declaration_list full_proc_block end_trigger
|
||||
{
|
||||
$$ = $1;
|
||||
$$->source = toString($6);
|
||||
$$->localDeclList = $4;
|
||||
$$->body = $5;
|
||||
}
|
||||
| function_clause_start external_clause external_body_clause_opt
|
||||
{
|
||||
$$ = $1;
|
||||
$$->external = $2;
|
||||
@ -1923,13 +1952,23 @@ function_clause_start
|
||||
{ $$ = FB_NEW(getPool()) CreateAlterFunctionNode(getPool(), compilingText, toName($1)); }
|
||||
input_parameters(&$2->parameters)
|
||||
RETURNS { $<legacyField>$ = lex.g_field = make_field(NULL); }
|
||||
domain_or_non_array_type collate_clause
|
||||
domain_or_non_array_type collate_clause deterministic_opt
|
||||
{
|
||||
$$ = $2;
|
||||
$$->returnType = TypeClause($<legacyField>5, toName($7));
|
||||
$$->invariant = ($8 != NULL);
|
||||
}
|
||||
;
|
||||
|
||||
deterministic_opt
|
||||
: DETERMINISTIC
|
||||
{ $$ = make_node (nod_flag, 0, NULL); }
|
||||
| NOT DETERMINISTIC
|
||||
{ $$ = NULL; }
|
||||
|
|
||||
{ $$ = NULL; }
|
||||
;
|
||||
|
||||
external_clause
|
||||
: EXTERNAL NAME sql_string ENGINE valid_symbol_name
|
||||
{
|
||||
@ -2198,6 +2237,8 @@ simple_proc_statement : assignment
|
||||
{ $$ = makeClassNode(FB_NEW(getPool()) SuspendNode(getPool())); }
|
||||
| EXIT
|
||||
{ $$ = makeClassNode(FB_NEW(getPool()) ExitNode(getPool())); }
|
||||
| RETURN value
|
||||
{ $$ = makeClassNode(FB_NEW(getPool()) ReturnNode(getPool(), $2)); }
|
||||
;
|
||||
|
||||
complex_proc_statement
|
||||
@ -3052,6 +3093,8 @@ keyword_or_column : valid_symbol_name
|
||||
| SIMILAR // added in FB 2.5
|
||||
| OVER // added in FB 3.0
|
||||
| SCROLL
|
||||
| RETURN
|
||||
| DETERMINISTIC
|
||||
;
|
||||
|
||||
col_opt : ALTER
|
||||
|
@ -11534,6 +11534,9 @@ void DSQL_pretty(const dsql_nod* node, int column)
|
||||
case nod_proc_obj:
|
||||
verb = "proc_obj";
|
||||
break;
|
||||
case nod_func_obj:
|
||||
verb = "func_obj";
|
||||
break;
|
||||
case nod_trig_obj:
|
||||
verb = "trig_obj";
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user