8
0
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:
asfernandes 2010-07-28 16:14:20 +00:00
parent 6ebf2864a0
commit 36f092fe0e
7 changed files with 62 additions and 6 deletions

View File

@ -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);

View File

@ -791,6 +791,7 @@ public:
dsql_nod* setDefault;
Firebird::MetaName renameTo;
Firebird::AutoPtr<TypeClause> type;
TriStateType<bool> nullFlag; // true = NULL / false = NOT NULL
};

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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;