mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:43:03 +01:00
Feature #7566 - Allow DEFAULT keyword in argument list.
This commit is contained in:
parent
5dbd5a46ef
commit
00a50429cb
@ -30,13 +30,18 @@ named arguments.
|
||||
[ {<positional arguments>,} ] <named arguments>
|
||||
|
||||
<positional arguments> ::=
|
||||
<value> [ {, <value>}... ]
|
||||
<value or default> [ {, <value or default>}... ]
|
||||
|
||||
<named arguments> ::=
|
||||
<named argument> [ {, <named argument>}... ]
|
||||
|
||||
<named argument> ::=
|
||||
<argument name> => <value>
|
||||
<argument name> => <value or default>
|
||||
|
||||
|
||||
<value or default> ::=
|
||||
<value> |
|
||||
DEFAULT
|
||||
```
|
||||
|
||||
## Examples
|
||||
@ -51,6 +56,11 @@ select function_name(1, parameter2 => 'Two')
|
||||
from rdb$database
|
||||
```
|
||||
|
||||
```
|
||||
select function_name(default, parameter2 => 'Two')
|
||||
from rdb$database
|
||||
```
|
||||
|
||||
```
|
||||
execute procedure insert_customer(
|
||||
last_name => 'SCHUMACHER',
|
||||
|
@ -13087,12 +13087,15 @@ DmlNode* UdfCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch*
|
||||
|
||||
for (auto& parameter : node->function->getInputFields())
|
||||
{
|
||||
if (const auto argValue = argsByName.get(parameter->prm_name))
|
||||
const auto argValue = argsByName.get(parameter->prm_name);
|
||||
|
||||
if (argValue)
|
||||
{
|
||||
*argIt = *argValue;
|
||||
argsByName.remove(parameter->prm_name);
|
||||
}
|
||||
else
|
||||
|
||||
if (!argValue || !*argValue)
|
||||
{
|
||||
if (parameter->prm_default_value)
|
||||
*argIt = CMP_clone_node(tdbb, csb, parameter->prm_default_value);
|
||||
@ -13185,7 +13188,7 @@ void UdfCallNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUShort(args->items.getCount());
|
||||
|
||||
for (auto& arg : args->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
|
||||
dsqlScratch->appendUChar(blr_end);
|
||||
|
||||
@ -13204,7 +13207,7 @@ void UdfCallNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUChar(args->items.getCount());
|
||||
|
||||
for (auto& arg : args->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
}
|
||||
|
||||
void UdfCallNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc)
|
||||
|
@ -3430,7 +3430,7 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||
|
||||
for (auto& arg : inputSources->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
}
|
||||
|
||||
// Output parameters.
|
||||
@ -3461,11 +3461,9 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
if (inputSources)
|
||||
{
|
||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||
auto ptr = inputSources->items.begin();
|
||||
const auto end = inputSources->items.end();
|
||||
|
||||
while (ptr < end)
|
||||
GEN_expr(dsqlScratch, *ptr++);
|
||||
for (auto& arg : inputSources->items)
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
}
|
||||
else
|
||||
dsqlScratch->appendUShort(0);
|
||||
@ -3474,10 +3472,9 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
if (outputSources)
|
||||
{
|
||||
dsqlScratch->appendUShort(outputSources->items.getCount());
|
||||
auto ptr = outputSources->items.begin();
|
||||
|
||||
for (const auto end = outputSources->items.end(); ptr != end; ++ptr)
|
||||
GEN_expr(dsqlScratch, *ptr);
|
||||
for (auto& arg : outputSources->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
}
|
||||
else
|
||||
dsqlScratch->appendUShort(0);
|
||||
|
@ -65,6 +65,17 @@ using namespace Firebird;
|
||||
static void gen_plan(DsqlCompilerScratch*, const PlanNode*);
|
||||
|
||||
|
||||
// Generate blr for an argument.
|
||||
// When it is nullptr, generate blr_default_arg.
|
||||
void GEN_arg(DsqlCompilerScratch* dsqlScratch, ExprNode* node)
|
||||
{
|
||||
if (node)
|
||||
GEN_expr(dsqlScratch, node);
|
||||
else
|
||||
dsqlScratch->appendUChar(blr_default_arg);
|
||||
}
|
||||
|
||||
|
||||
void GEN_hidden_variables(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
/**************************************
|
||||
|
@ -30,6 +30,7 @@ namespace Jrd
|
||||
class ValueListNode;
|
||||
}
|
||||
|
||||
void GEN_arg(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
|
||||
void GEN_descriptor(Jrd::DsqlCompilerScratch* dsqlScratch, const dsc* desc, bool texttype);
|
||||
void GEN_expr(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
|
||||
void GEN_hidden_variables(Jrd::DsqlCompilerScratch* dsqlScratch);
|
||||
|
@ -8618,12 +8618,12 @@ argument_list_opt
|
||||
%type <namedArguments> argument_list
|
||||
argument_list
|
||||
: named_argument_list
|
||||
| value_list
|
||||
| value_or_default_list
|
||||
{
|
||||
$$ = newNode<NonPooledPair<ObjectsArray<MetaName>*, ValueListNode*>>();
|
||||
$$->second = $1;
|
||||
}
|
||||
| value_list ',' named_argument_list
|
||||
| value_or_default_list ',' named_argument_list
|
||||
{
|
||||
$$ = $3;
|
||||
|
||||
@ -8655,7 +8655,7 @@ named_argument_list
|
||||
|
||||
%type <namedArgument> named_argument
|
||||
named_argument
|
||||
: symbol_column_name NAMED_ARG_ASSIGN value
|
||||
: symbol_column_name NAMED_ARG_ASSIGN value_or_default
|
||||
{ $$ = newNode<NonPooledPair<MetaName*, ValueExprNode*>>($1, $3); }
|
||||
;
|
||||
|
||||
|
@ -492,4 +492,6 @@
|
||||
#define blr_invsel_procedure_context (unsigned char) 6
|
||||
#define blr_invsel_procedure_alias (unsigned char) 7
|
||||
|
||||
#define blr_default_arg (unsigned char) 227
|
||||
|
||||
#endif // FIREBIRD_IMPL_BLR_H
|
||||
|
@ -970,5 +970,5 @@ FB_IMPL_MSG(JRD, 967, idx_expr_not_found, -902, "42", "000", "Definition of inde
|
||||
FB_IMPL_MSG(JRD, 968, idx_cond_not_found, -902, "42", "000", "Definition of index condition is not found for index @1")
|
||||
FB_IMPL_MSG(JRD, 969, uninitialized_var, -625, "42", "000", "Variable @1 is not initialized")
|
||||
FB_IMPL_MSG(JRD, 970, param_not_exist, -170, "07", "001", "Parameter @1 does not exist")
|
||||
FB_IMPL_MSG(JRD, 971, param_no_default_not_specified, -170, "07", "001", "Parameter @1 has no default value and was not specified")
|
||||
FB_IMPL_MSG(JRD, 971, param_no_default_not_specified, -170, "07", "001", "Parameter @1 has no default value and was not specified or was specified with DEFAULT")
|
||||
FB_IMPL_MSG(JRD, 972, param_multiple_assignments, -170, "07", "001", "Parameter @1 has multiple assignments")
|
||||
|
@ -1294,7 +1294,7 @@ void ProcedureSourceNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||
|
||||
for (auto& arg : inputSources->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
}
|
||||
|
||||
if (dsqlContext->ctx_context > MAX_UCHAR)
|
||||
@ -1355,7 +1355,7 @@ void ProcedureSourceNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||
|
||||
for (auto& arg : inputSources->items)
|
||||
GEN_expr(dsqlScratch, arg);
|
||||
GEN_arg(dsqlScratch, arg);
|
||||
}
|
||||
else
|
||||
dsqlScratch->appendUShort(0);
|
||||
|
@ -258,5 +258,6 @@ static const struct
|
||||
{"invoke_function", invoke_function},
|
||||
{"invoke_procedure", invsel_procedure},
|
||||
{"select_procedure", invsel_procedure},
|
||||
{"blr_default_arg", zero},
|
||||
{0, 0}
|
||||
};
|
||||
|
@ -553,12 +553,15 @@ Arg::StatusVector CMP_procedure_arguments(
|
||||
|
||||
for (auto& parameter : fields)
|
||||
{
|
||||
if (const auto argValue = argsByName.get(parameter->prm_name))
|
||||
const auto argValue = argsByName.get(parameter->prm_name);
|
||||
|
||||
if (argValue)
|
||||
{
|
||||
*sourceArgIt = *argValue;
|
||||
argsByName.remove(parameter->prm_name);
|
||||
}
|
||||
else if (isInput)
|
||||
|
||||
if (isInput && (!argValue || !*argValue))
|
||||
{
|
||||
if (parameter->prm_default_value)
|
||||
*sourceArgIt = CMP_clone_node(tdbb, csb, parameter->prm_default_value);
|
||||
|
@ -804,7 +804,12 @@ ValueListNode* PAR_args(thread_db* tdbb, CompilerScratch* csb, USHORT count, USH
|
||||
{
|
||||
do
|
||||
{
|
||||
*ptr++ = PAR_parse_value(tdbb, csb);
|
||||
if (csb->csb_blr_reader.peekByte() == blr_default_arg)
|
||||
csb->csb_blr_reader.getByte();
|
||||
else
|
||||
*ptr = PAR_parse_value(tdbb, csb);
|
||||
|
||||
++ptr;
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user