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>,} ] <named arguments>
|
||||||
|
|
||||||
<positional arguments> ::=
|
<positional arguments> ::=
|
||||||
<value> [ {, <value>}... ]
|
<value or default> [ {, <value or default>}... ]
|
||||||
|
|
||||||
<named arguments> ::=
|
<named arguments> ::=
|
||||||
<named argument> [ {, <named argument>}... ]
|
<named argument> [ {, <named argument>}... ]
|
||||||
|
|
||||||
<named argument> ::=
|
<named argument> ::=
|
||||||
<argument name> => <value>
|
<argument name> => <value or default>
|
||||||
|
|
||||||
|
|
||||||
|
<value or default> ::=
|
||||||
|
<value> |
|
||||||
|
DEFAULT
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
@ -51,6 +56,11 @@ select function_name(1, parameter2 => 'Two')
|
|||||||
from rdb$database
|
from rdb$database
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
select function_name(default, parameter2 => 'Two')
|
||||||
|
from rdb$database
|
||||||
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
execute procedure insert_customer(
|
execute procedure insert_customer(
|
||||||
last_name => 'SCHUMACHER',
|
last_name => 'SCHUMACHER',
|
||||||
|
@ -13087,12 +13087,15 @@ DmlNode* UdfCallNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch*
|
|||||||
|
|
||||||
for (auto& parameter : node->function->getInputFields())
|
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;
|
*argIt = *argValue;
|
||||||
argsByName.remove(parameter->prm_name);
|
argsByName.remove(parameter->prm_name);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!argValue || !*argValue)
|
||||||
{
|
{
|
||||||
if (parameter->prm_default_value)
|
if (parameter->prm_default_value)
|
||||||
*argIt = CMP_clone_node(tdbb, csb, 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());
|
dsqlScratch->appendUShort(args->items.getCount());
|
||||||
|
|
||||||
for (auto& arg : args->items)
|
for (auto& arg : args->items)
|
||||||
GEN_expr(dsqlScratch, arg);
|
GEN_arg(dsqlScratch, arg);
|
||||||
|
|
||||||
dsqlScratch->appendUChar(blr_end);
|
dsqlScratch->appendUChar(blr_end);
|
||||||
|
|
||||||
@ -13204,7 +13207,7 @@ void UdfCallNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
dsqlScratch->appendUChar(args->items.getCount());
|
dsqlScratch->appendUChar(args->items.getCount());
|
||||||
|
|
||||||
for (auto& arg : args->items)
|
for (auto& arg : args->items)
|
||||||
GEN_expr(dsqlScratch, arg);
|
GEN_arg(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UdfCallNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc)
|
void UdfCallNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc)
|
||||||
|
@ -3430,7 +3430,7 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||||
|
|
||||||
for (auto& arg : inputSources->items)
|
for (auto& arg : inputSources->items)
|
||||||
GEN_expr(dsqlScratch, arg);
|
GEN_arg(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output parameters.
|
// Output parameters.
|
||||||
@ -3461,11 +3461,9 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
if (inputSources)
|
if (inputSources)
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||||
auto ptr = inputSources->items.begin();
|
|
||||||
const auto end = inputSources->items.end();
|
|
||||||
|
|
||||||
while (ptr < end)
|
for (auto& arg : inputSources->items)
|
||||||
GEN_expr(dsqlScratch, *ptr++);
|
GEN_arg(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dsqlScratch->appendUShort(0);
|
dsqlScratch->appendUShort(0);
|
||||||
@ -3474,10 +3472,9 @@ void ExecProcedureNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
if (outputSources)
|
if (outputSources)
|
||||||
{
|
{
|
||||||
dsqlScratch->appendUShort(outputSources->items.getCount());
|
dsqlScratch->appendUShort(outputSources->items.getCount());
|
||||||
auto ptr = outputSources->items.begin();
|
|
||||||
|
|
||||||
for (const auto end = outputSources->items.end(); ptr != end; ++ptr)
|
for (auto& arg : outputSources->items)
|
||||||
GEN_expr(dsqlScratch, *ptr);
|
GEN_expr(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dsqlScratch->appendUShort(0);
|
dsqlScratch->appendUShort(0);
|
||||||
|
@ -65,6 +65,17 @@ using namespace Firebird;
|
|||||||
static void gen_plan(DsqlCompilerScratch*, const PlanNode*);
|
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)
|
void GEN_hidden_variables(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -30,6 +30,7 @@ namespace Jrd
|
|||||||
class ValueListNode;
|
class ValueListNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GEN_arg(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
|
||||||
void GEN_descriptor(Jrd::DsqlCompilerScratch* dsqlScratch, const dsc* desc, bool texttype);
|
void GEN_descriptor(Jrd::DsqlCompilerScratch* dsqlScratch, const dsc* desc, bool texttype);
|
||||||
void GEN_expr(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
|
void GEN_expr(Jrd::DsqlCompilerScratch*, Jrd::ExprNode*);
|
||||||
void GEN_hidden_variables(Jrd::DsqlCompilerScratch* dsqlScratch);
|
void GEN_hidden_variables(Jrd::DsqlCompilerScratch* dsqlScratch);
|
||||||
|
@ -8618,12 +8618,12 @@ argument_list_opt
|
|||||||
%type <namedArguments> argument_list
|
%type <namedArguments> argument_list
|
||||||
argument_list
|
argument_list
|
||||||
: named_argument_list
|
: named_argument_list
|
||||||
| value_list
|
| value_or_default_list
|
||||||
{
|
{
|
||||||
$$ = newNode<NonPooledPair<ObjectsArray<MetaName>*, ValueListNode*>>();
|
$$ = newNode<NonPooledPair<ObjectsArray<MetaName>*, ValueListNode*>>();
|
||||||
$$->second = $1;
|
$$->second = $1;
|
||||||
}
|
}
|
||||||
| value_list ',' named_argument_list
|
| value_or_default_list ',' named_argument_list
|
||||||
{
|
{
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
|
|
||||||
@ -8655,7 +8655,7 @@ named_argument_list
|
|||||||
|
|
||||||
%type <namedArgument> named_argument
|
%type <namedArgument> named_argument
|
||||||
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); }
|
{ $$ = newNode<NonPooledPair<MetaName*, ValueExprNode*>>($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -492,4 +492,6 @@
|
|||||||
#define blr_invsel_procedure_context (unsigned char) 6
|
#define blr_invsel_procedure_context (unsigned char) 6
|
||||||
#define blr_invsel_procedure_alias (unsigned char) 7
|
#define blr_invsel_procedure_alias (unsigned char) 7
|
||||||
|
|
||||||
|
#define blr_default_arg (unsigned char) 227
|
||||||
|
|
||||||
#endif // FIREBIRD_IMPL_BLR_H
|
#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, 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, 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, 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")
|
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());
|
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||||
|
|
||||||
for (auto& arg : inputSources->items)
|
for (auto& arg : inputSources->items)
|
||||||
GEN_expr(dsqlScratch, arg);
|
GEN_arg(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsqlContext->ctx_context > MAX_UCHAR)
|
if (dsqlContext->ctx_context > MAX_UCHAR)
|
||||||
@ -1355,7 +1355,7 @@ void ProcedureSourceNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
dsqlScratch->appendUShort(inputSources->items.getCount());
|
dsqlScratch->appendUShort(inputSources->items.getCount());
|
||||||
|
|
||||||
for (auto& arg : inputSources->items)
|
for (auto& arg : inputSources->items)
|
||||||
GEN_expr(dsqlScratch, arg);
|
GEN_arg(dsqlScratch, arg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dsqlScratch->appendUShort(0);
|
dsqlScratch->appendUShort(0);
|
||||||
|
@ -258,5 +258,6 @@ static const struct
|
|||||||
{"invoke_function", invoke_function},
|
{"invoke_function", invoke_function},
|
||||||
{"invoke_procedure", invsel_procedure},
|
{"invoke_procedure", invsel_procedure},
|
||||||
{"select_procedure", invsel_procedure},
|
{"select_procedure", invsel_procedure},
|
||||||
|
{"blr_default_arg", zero},
|
||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
@ -553,12 +553,15 @@ Arg::StatusVector CMP_procedure_arguments(
|
|||||||
|
|
||||||
for (auto& parameter : fields)
|
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;
|
*sourceArgIt = *argValue;
|
||||||
argsByName.remove(parameter->prm_name);
|
argsByName.remove(parameter->prm_name);
|
||||||
}
|
}
|
||||||
else if (isInput)
|
|
||||||
|
if (isInput && (!argValue || !*argValue))
|
||||||
{
|
{
|
||||||
if (parameter->prm_default_value)
|
if (parameter->prm_default_value)
|
||||||
*sourceArgIt = CMP_clone_node(tdbb, csb, 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
|
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);
|
} while (--count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user