mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 10:40:38 +01:00
Improvement CORE-3085 - Add clause ALTER DOMAIN <name> [NOT] NULL
This commit is contained in:
parent
6ebf2864a0
commit
36f092fe0e
@ -4136,6 +4136,12 @@ void AlterDomainNode::execute(thread_db* tdbb, jrd_tra* transaction)
|
||||
dsqlScratch->getBlrData());
|
||||
}
|
||||
|
||||
if (nullFlag.specified)
|
||||
{
|
||||
FLD.RDB$NULL_FLAG.NULL = FALSE;
|
||||
FLD.RDB$NULL_FLAG = nullFlag.value ? 0 : 1;
|
||||
}
|
||||
|
||||
if (type)
|
||||
{
|
||||
type->resolve(dsqlScratch);
|
||||
|
@ -791,6 +791,7 @@ public:
|
||||
dsql_nod* setDefault;
|
||||
Firebird::MetaName renameTo;
|
||||
Firebird::AutoPtr<TypeClause> type;
|
||||
TriStateType<bool> nullFlag; // true = NULL / false = NOT NULL
|
||||
};
|
||||
|
||||
|
||||
|
@ -166,6 +166,20 @@ private:
|
||||
clause = value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setClause(TriStateType<T>& clause, const char* duplicateMsg, const T& value)
|
||||
{
|
||||
using namespace Firebird;
|
||||
if (clause.specified)
|
||||
{
|
||||
status_exception::raise(
|
||||
Arg::Gds(isc_sqlerr) << Arg::Num(-637) <<
|
||||
Arg::Gds(isc_dsql_duplicate_spec) << duplicateMsg);
|
||||
}
|
||||
|
||||
clause = value;
|
||||
}
|
||||
|
||||
void setClause(bool& clause, const char* duplicateMsg)
|
||||
{
|
||||
setClause(clause, duplicateMsg, true);
|
||||
|
@ -3124,6 +3124,10 @@ alter_domain_op($alterDomainNode)
|
||||
{ setClause($alterDomainNode->dropDefault, "DOMAIN DROP DEFAULT"); }
|
||||
| DROP CONSTRAINT
|
||||
{ setClause($alterDomainNode->dropConstraint, "DOMAIN DROP CONSTRAINT"); }
|
||||
| KW_NULL
|
||||
{ setClause($alterDomainNode->nullFlag, "[NOT] NULL", true); }
|
||||
| NOT KW_NULL
|
||||
{ setClause($alterDomainNode->nullFlag, "[NOT] NULL", false); }
|
||||
| TO symbol_column_name
|
||||
{ setClause($alterDomainNode->renameTo, "DOMAIN NAME", toName($2)); }
|
||||
| KW_TYPE init_data_type non_array_type
|
||||
|
@ -3341,9 +3341,31 @@ static bool modify_field(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_
|
||||
{
|
||||
const Firebird::MetaName depName(work->dfw_name);
|
||||
AutoRequest handle;
|
||||
|
||||
// If a domain is being changed to NOT NULL, schedule validation for involved relations.
|
||||
if (work->findArg(dfw_arg_field_null))
|
||||
{
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
RFL IN RDB$RELATION_FIELDS
|
||||
WITH RFL.RDB$FIELD_SOURCE EQ depName.c_str()
|
||||
REDUCED TO RFL.RDB$RELATION_NAME, RFL.RDB$FIELD_ID
|
||||
{
|
||||
dsc desc;
|
||||
desc.makeText(strlen(RFL.RDB$RELATION_NAME), CS_METADATA,
|
||||
(UCHAR*) RFL.RDB$RELATION_NAME);
|
||||
|
||||
DeferredWork* work = DFW_post_work(transaction, dfw_check_not_null, &desc, 0);
|
||||
SortedArray<int>& ids = DFW_get_ids(work);
|
||||
ids.add(RFL.RDB$FIELD_ID);
|
||||
}
|
||||
END_FOR
|
||||
}
|
||||
|
||||
bid validation;
|
||||
validation.clear();
|
||||
|
||||
handle.reset();
|
||||
|
||||
FOR(REQUEST_HANDLE handle)
|
||||
FLD IN RDB$FIELDS WITH
|
||||
FLD.RDB$FIELD_NAME EQ depName.c_str()
|
||||
@ -5124,7 +5146,7 @@ static bool make_version(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_
|
||||
|
||||
DeferredWork* work = DFW_post_work(transaction,
|
||||
dfw_check_not_null, &desc, 0);
|
||||
Array<int>& ids = DFW_get_ids(work);
|
||||
SortedArray<int>& ids = DFW_get_ids(work);
|
||||
ids.add(RFR.RDB$FIELD_ID);
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +455,8 @@ enum dfw_t {
|
||||
dfw_arg_check_blr, // check if BLR is still compilable
|
||||
dfw_arg_rel_name, // relation name of a trigger
|
||||
dfw_arg_trg_type, // trigger type
|
||||
dfw_arg_new_name // new name
|
||||
dfw_arg_new_name, // new name
|
||||
dfw_arg_field_null
|
||||
};
|
||||
|
||||
// Verb actions
|
||||
|
@ -2344,7 +2344,7 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
EVL_field(0, new_rpb->rpb_record, f_rfr_id, &desc2);
|
||||
|
||||
DeferredWork* work = DFW_post_work(transaction, dfw_check_not_null, &desc1, 0);
|
||||
Array<int>& ids = DFW_get_ids(work);
|
||||
SortedArray<int>& ids = DFW_get_ids(work);
|
||||
ids.add(MOV_get_long(&desc2, 0));
|
||||
}
|
||||
}
|
||||
@ -2359,6 +2359,9 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
MET_change_fields(tdbb, transaction, &desc1);
|
||||
EVL_field(0, new_rpb->rpb_record, f_fld_name, &desc2);
|
||||
DeferredWork* dw = MET_change_fields(tdbb, transaction, &desc2);
|
||||
dsc desc3, desc4;
|
||||
bool rc1, rc2;
|
||||
|
||||
if (dw)
|
||||
{
|
||||
// Did we convert computed field into physical, stored field?
|
||||
@ -2366,9 +2369,8 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
// Warning: getting the result of MET_change_fields is the last relation
|
||||
// that was affected, but for computed fields, it's an implicit domain
|
||||
// and hence it can be used only by a single field and therefore one relation.
|
||||
dsc desc3, desc4;
|
||||
bool rc1 = EVL_field(0, org_rpb->rpb_record, f_fld_computed, &desc3);
|
||||
bool rc2 = EVL_field(0, new_rpb->rpb_record, f_fld_computed, &desc4);
|
||||
rc1 = EVL_field(0, org_rpb->rpb_record, f_fld_computed, &desc3);
|
||||
rc2 = EVL_field(0, new_rpb->rpb_record, f_fld_computed, &desc4);
|
||||
if (rc1 != rc2 || rc1 && MOV_compare(&desc3, &desc4)) {
|
||||
DFW_post_work_arg(transaction, dw, &desc1, 0, dfw_arg_force_computed);
|
||||
}
|
||||
@ -2376,6 +2378,12 @@ void VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j
|
||||
|
||||
dw = DFW_post_work(transaction, dfw_modify_field, &desc1, 0);
|
||||
DFW_post_work_arg(transaction, dw, &desc2, 0, dfw_arg_new_name);
|
||||
|
||||
rc1 = EVL_field(NULL, org_rpb->rpb_record, f_fld_null_flag, &desc3);
|
||||
rc2 = EVL_field(NULL, new_rpb->rpb_record, f_fld_null_flag, &desc4);
|
||||
|
||||
if ((!rc1 || MOV_get_long(&desc3, 0) == 0) && rc2 && MOV_get_long(&desc4, 0) != 0)
|
||||
DFW_post_work_arg(transaction, dw, &desc2, 0, dfw_arg_field_null);
|
||||
}
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user