mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 07:23:04 +01:00
Refactor DSQL's nod_field
This commit is contained in:
parent
667caf5257
commit
4a9f98bed7
@ -7392,9 +7392,10 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dsql_fld* nameField = NULL;
|
const dsql_fld* nameField = NULL;
|
||||||
|
const FieldNode* fieldNameNode = ExprNode::as<FieldNode>(nameNode);
|
||||||
|
|
||||||
if (nameNode->nod_type == Dsql::nod_field)
|
if (fieldNameNode)
|
||||||
nameField = (dsql_fld*) nameNode->nod_arg[Dsql::e_fld_field];
|
nameField = fieldNameNode->dsqlField;
|
||||||
|
|
||||||
const TEXT* fieldStr = NULL;
|
const TEXT* fieldStr = NULL;
|
||||||
|
|
||||||
@ -7411,10 +7412,12 @@ void CreateAlterViewNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
|||||||
dsql_fld* field = NULL;
|
dsql_fld* field = NULL;
|
||||||
const dsql_ctx* context = NULL;
|
const dsql_ctx* context = NULL;
|
||||||
|
|
||||||
if (fieldNode->nod_type == Dsql::nod_field)
|
fieldNameNode = ExprNode::as<FieldNode>(fieldNode);
|
||||||
|
|
||||||
|
if (fieldNameNode)
|
||||||
{
|
{
|
||||||
field = (dsql_fld*) fieldNode->nod_arg[Dsql::e_fld_field];
|
field = fieldNameNode->dsqlField;
|
||||||
context = (dsql_ctx*) fieldNode->nod_arg[Dsql::e_fld_context];
|
context = fieldNameNode->dsqlContext;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
updatable = false;
|
updatable = false;
|
||||||
@ -8064,8 +8067,8 @@ dsql_nod* CreateAlterViewNode::replaceFieldNames(dsql_nod* input, dsql_nod* sear
|
|||||||
if (replaceFields)
|
if (replaceFields)
|
||||||
replaceName = (dsql_str*) (*replace)->nod_arg[Dsql::e_fln_name];
|
replaceName = (dsql_str*) (*replace)->nod_arg[Dsql::e_fln_name];
|
||||||
|
|
||||||
const dsql_nod* fieldNode = *search;
|
const FieldNode* fieldNode = ExprNode::as<FieldNode>(*search);
|
||||||
const dsql_fld* field = (dsql_fld*) fieldNode->nod_arg[Dsql::e_fld_field];
|
const dsql_fld* field = fieldNode->dsqlField;
|
||||||
|
|
||||||
if (field->fld_name == fieldName->str_data)
|
if (field->fld_name == fieldName->str_data)
|
||||||
{
|
{
|
||||||
|
@ -4202,12 +4202,16 @@ static RegisterNode<FieldNode> regFieldNodeField(blr_field);
|
|||||||
|
|
||||||
FieldNode::FieldNode(MemoryPool& pool)
|
FieldNode::FieldNode(MemoryPool& pool)
|
||||||
: TypedNode<ValueExprNode, ExprNode::TYPE_FIELD>(pool),
|
: TypedNode<ValueExprNode, ExprNode::TYPE_FIELD>(pool),
|
||||||
|
dsqlContext(NULL),
|
||||||
|
dsqlField(NULL),
|
||||||
|
dsqlIndices(NULL),
|
||||||
byId(false),
|
byId(false),
|
||||||
fieldStream(0),
|
fieldStream(0),
|
||||||
fieldId(0),
|
fieldId(0),
|
||||||
format(NULL),
|
format(NULL),
|
||||||
defaultValue(NULL)
|
defaultValue(NULL)
|
||||||
{
|
{
|
||||||
|
dsqlDesc.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse a field.
|
// Parse a field.
|
||||||
@ -4383,40 +4387,191 @@ void FieldNode::print(string& text, Array<dsql_nod*>& nodes) const
|
|||||||
ExprNode::print(text, nodes);
|
ExprNode::print(text, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// TODO: Implement FieldNode DSQL support.
|
|
||||||
|
|
||||||
ValueExprNode* FieldNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
ValueExprNode* FieldNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
|
// AB: nod_field is an already passed node.
|
||||||
|
// This could be done in expand_select_list.
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlAggregateFinder(AggregateFinder& visitor)
|
||||||
|
{
|
||||||
|
if (visitor.deepestLevel < dsqlContext->ctx_scope_level)
|
||||||
|
visitor.deepestLevel = dsqlContext->ctx_scope_level;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlAggregate2Finder(Aggregate2Finder& visitor)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor)
|
||||||
|
{
|
||||||
|
// Wouldn't it be better to call an error from this point where return is true?
|
||||||
|
// Then we could give the fieldname that's making the trouble.
|
||||||
|
|
||||||
|
// If we come here then this field is used inside a aggregate-function. The
|
||||||
|
// ctx_scope_level gives the info how deep the context is inside the statement.
|
||||||
|
|
||||||
|
// If the context-scope-level from this field is lower or the same as the scope-level
|
||||||
|
// from the given context then it is an invalid field.
|
||||||
|
if (dsqlContext->ctx_scope_level == visitor.context->ctx_scope_level)
|
||||||
|
{
|
||||||
|
// Return true (invalid) if this field isn't inside the GROUP BY clause, that
|
||||||
|
// should already been seen in the match_node test in that routine start.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlSubSelectFinder(SubSelectFinder& visitor)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlFieldFinder(FieldFinder& visitor)
|
||||||
|
{
|
||||||
|
visitor.field = true;
|
||||||
|
|
||||||
|
switch (visitor.matchType)
|
||||||
|
{
|
||||||
|
case FIELD_MATCH_TYPE_EQUAL:
|
||||||
|
return dsqlContext->ctx_scope_level == visitor.checkScopeLevel;
|
||||||
|
|
||||||
|
case FIELD_MATCH_TYPE_LOWER:
|
||||||
|
return dsqlContext->ctx_scope_level < visitor.checkScopeLevel;
|
||||||
|
|
||||||
|
case FIELD_MATCH_TYPE_LOWER_EQUAL:
|
||||||
|
return dsqlContext->ctx_scope_level <= visitor.checkScopeLevel;
|
||||||
|
|
||||||
|
///case FIELD_MATCH_TYPE_HIGHER:
|
||||||
|
/// return dsqlContext->ctx_scope_level > visitor.checkScopeLevel;
|
||||||
|
|
||||||
|
///case FIELD_MATCH_TYPE_HIGHER_EQUAL:
|
||||||
|
/// return dsqlContext->ctx_scope_level >= visitor.checkScopeLevel;
|
||||||
|
|
||||||
|
default:
|
||||||
fb_assert(false);
|
fb_assert(false);
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FieldNode::dsqlFieldRemapper(FieldRemapper& visitor)
|
||||||
|
{
|
||||||
|
if (dsqlContext->ctx_scope_level == visitor.context->ctx_scope_level)
|
||||||
|
{
|
||||||
|
visitor.replaceNode(PASS1_post_map(visitor.dsqlScratch, this, visitor.context,
|
||||||
|
visitor.partitionNode, visitor.orderNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldNode::setParameterName(dsql_par* parameter) const
|
void FieldNode::setParameterName(dsql_par* parameter) const
|
||||||
{
|
{
|
||||||
fb_assert(false);
|
parameter->par_name = parameter->par_alias = dsqlField->fld_name.c_str();
|
||||||
|
|
||||||
|
if (dsqlContext->ctx_relation)
|
||||||
|
{
|
||||||
|
parameter->par_rel_name = dsqlContext->ctx_relation->rel_name.c_str();
|
||||||
|
parameter->par_owner_name = dsqlContext->ctx_relation->rel_owner.c_str();
|
||||||
|
}
|
||||||
|
else if (dsqlContext->ctx_procedure)
|
||||||
|
{
|
||||||
|
parameter->par_rel_name = dsqlContext->ctx_procedure->prc_name.identifier.c_str();
|
||||||
|
parameter->par_owner_name = dsqlContext->ctx_procedure->prc_owner.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parameter->par_rel_alias = dsqlContext->ctx_alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate blr for a field - field id's are preferred but not for trigger or view blr.
|
||||||
void FieldNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
void FieldNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||||
{
|
{
|
||||||
fb_assert(false);
|
// For older clients - generate an error should they try and
|
||||||
|
// access data types which did not exist in the older dialect.
|
||||||
|
if (dsqlScratch->clientDialect <= SQL_DIALECT_V5)
|
||||||
|
{
|
||||||
|
switch (dsqlField->fld_dtype)
|
||||||
|
{
|
||||||
|
case dtype_sql_date:
|
||||||
|
case dtype_sql_time:
|
||||||
|
case dtype_int64:
|
||||||
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
|
||||||
|
Arg::Gds(isc_dsql_datatype_err) <<
|
||||||
|
Arg::Gds(isc_sql_dialect_datatype_unsupport) <<
|
||||||
|
Arg::Num(dsqlScratch->clientDialect) <<
|
||||||
|
Arg::Str(DSC_dtype_tostring(static_cast<UCHAR>(dsqlField->fld_dtype))));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// No special action for other data types
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsqlIndices)
|
||||||
|
dsqlScratch->appendUChar(blr_index);
|
||||||
|
|
||||||
|
if (DDL_ids(dsqlScratch))
|
||||||
|
{
|
||||||
|
dsqlScratch->appendUChar(blr_fid);
|
||||||
|
GEN_stuff_context(dsqlScratch, dsqlContext);
|
||||||
|
dsqlScratch->appendUShort(dsqlField->fld_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dsqlScratch->appendUChar(blr_field);
|
||||||
|
GEN_stuff_context(dsqlScratch, dsqlContext);
|
||||||
|
dsqlScratch->appendMetaString(dsqlField->fld_name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsqlIndices)
|
||||||
|
{
|
||||||
|
dsqlScratch->appendUChar(dsqlIndices->nod_count);
|
||||||
|
dsql_nod** ptr = dsqlIndices->nod_arg;
|
||||||
|
|
||||||
|
for (const dsql_nod* const* end = ptr + dsqlIndices->nod_count; ptr != end; ++ptr)
|
||||||
|
GEN_expr(dsqlScratch, *ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc)
|
void FieldNode::make(DsqlCompilerScratch* /*dsqlScratch*/, dsc* desc)
|
||||||
{
|
{
|
||||||
fb_assert(false);
|
if (dsqlDesc.dsc_dtype)
|
||||||
|
*desc = dsqlDesc;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-203) <<
|
||||||
|
Arg::Gds(isc_dsql_field_ref));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FieldNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const
|
bool FieldNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const
|
||||||
{
|
{
|
||||||
fb_assert(false);
|
if (!ExprNode::dsqlMatch(other, ignoreMapCast))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const FieldNode* o = other->as<FieldNode>();
|
||||||
|
fb_assert(o)
|
||||||
|
|
||||||
|
if (dsqlField != o->dsqlField || dsqlContext != o->dsqlContext)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (dsqlIndices || o->dsqlIndices)
|
||||||
|
return PASS1_node_match(dsqlIndices, o->dsqlIndices, ignoreMapCast);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FieldNode::expressionEqual(thread_db* tdbb, CompilerScratch* csb, /*const*/ ExprNode* other,
|
bool FieldNode::expressionEqual(thread_db* tdbb, CompilerScratch* csb, /*const*/ ExprNode* other,
|
||||||
USHORT stream) /*const*/
|
USHORT stream) /*const*/
|
||||||
{
|
{
|
||||||
const FieldNode* o = other->as<FieldNode>();
|
const FieldNode* o = other->as<FieldNode>();
|
||||||
// ASF: Why not test fieldStream == o->fieldStream?
|
|
||||||
return o && fieldId == o->fieldId && o->fieldStream == stream;
|
return o && fieldId == o->fieldId && o->fieldStream == stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5626,30 +5781,17 @@ void DsqlMapNode::setParameterName(dsql_par* parameter) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* nameAlias = NULL;
|
const char* nameAlias = NULL;
|
||||||
const dsql_ctx* context = NULL;
|
const FieldNode* fieldNode = NULL;
|
||||||
const dsql_fld* field;
|
|
||||||
const dsql_nod* alias;
|
const dsql_nod* alias;
|
||||||
const dsql_str* str;
|
const dsql_str* str;
|
||||||
|
|
||||||
switch (nestNode->nod_type)
|
switch (nestNode->nod_type)
|
||||||
{
|
{
|
||||||
case Dsql::nod_field:
|
|
||||||
field = (dsql_fld*) nestNode->nod_arg[Dsql::e_fld_field];
|
|
||||||
nameAlias = field->fld_name.c_str();
|
|
||||||
context = (dsql_ctx*) nestNode->nod_arg[Dsql::e_fld_context];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Dsql::nod_alias:
|
case Dsql::nod_alias:
|
||||||
str = (dsql_str*) nestNode->nod_arg[Dsql::e_alias_alias];
|
str = (dsql_str*) nestNode->nod_arg[Dsql::e_alias_alias];
|
||||||
parameter->par_alias = str->str_data;
|
parameter->par_alias = str->str_data;
|
||||||
alias = nestNode->nod_arg[Dsql::e_alias_value];
|
alias = nestNode->nod_arg[Dsql::e_alias_value];
|
||||||
|
fieldNode = ExprNode::as<FieldNode>(alias);
|
||||||
if (alias->nod_type == Dsql::nod_field)
|
|
||||||
{
|
|
||||||
field = (dsql_fld*) alias->nod_arg[Dsql::e_fld_field];
|
|
||||||
parameter->par_name = field->fld_name.c_str();
|
|
||||||
context = (dsql_ctx*) alias->nod_arg[Dsql::e_fld_context];
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Dsql::nod_class_exprnode:
|
case Dsql::nod_class_exprnode:
|
||||||
@ -5668,19 +5810,25 @@ void DsqlMapNode::setParameterName(dsql_par* parameter) const
|
|||||||
{
|
{
|
||||||
parameter->par_alias = derivedField->name;
|
parameter->par_alias = derivedField->name;
|
||||||
alias = derivedField->dsqlValue;
|
alias = derivedField->dsqlValue;
|
||||||
|
fieldNode = ExprNode::as<FieldNode>(alias);
|
||||||
if (alias->nod_type == Dsql::nod_field)
|
|
||||||
{
|
|
||||||
field = (dsql_fld*) alias->nod_arg[Dsql::e_fld_field];
|
|
||||||
parameter->par_name = field->fld_name.c_str();
|
|
||||||
context = (dsql_ctx*) alias->nod_arg[Dsql::e_fld_context];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if ((fieldNode = ExprNode::as<FieldNode>(nestNode)))
|
||||||
|
nameAlias = fieldNode->dsqlField->fld_name.c_str();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // switch(nestNode->nod_type)
|
} // switch(nestNode->nod_type)
|
||||||
|
|
||||||
|
const dsql_ctx* context = NULL;
|
||||||
|
const dsql_fld* field;
|
||||||
|
|
||||||
|
if (fieldNode)
|
||||||
|
{
|
||||||
|
context = fieldNode->dsqlContext;
|
||||||
|
field = fieldNode->dsqlField;
|
||||||
|
parameter->par_name = field->fld_name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
if (nameAlias)
|
if (nameAlias)
|
||||||
parameter->par_name = parameter->par_alias = nameAlias;
|
parameter->par_name = parameter->par_alias = nameAlias;
|
||||||
|
|
||||||
@ -5836,13 +5984,13 @@ bool DerivedFieldNode::dsqlFieldRemapper(FieldRemapper& visitor)
|
|||||||
void DerivedFieldNode::setParameterName(dsql_par* parameter) const
|
void DerivedFieldNode::setParameterName(dsql_par* parameter) const
|
||||||
{
|
{
|
||||||
const dsql_ctx* context = NULL;
|
const dsql_ctx* context = NULL;
|
||||||
|
const FieldNode* fieldNode;
|
||||||
const RecordKeyNode* dbKeyNode;
|
const RecordKeyNode* dbKeyNode;
|
||||||
|
|
||||||
if (dsqlValue->nod_type == Dsql::nod_field)
|
if ((fieldNode = ExprNode::as<FieldNode>(dsqlValue)))
|
||||||
{
|
{
|
||||||
dsql_fld* field = (dsql_fld*) dsqlValue->nod_arg[Dsql::e_fld_field];
|
parameter->par_name = fieldNode->dsqlField->fld_name.c_str();
|
||||||
parameter->par_name = field->fld_name.c_str();
|
context = fieldNode->dsqlContext;
|
||||||
context = (dsql_ctx*) dsqlValue->nod_arg[Dsql::e_fld_context];
|
|
||||||
}
|
}
|
||||||
else if ((dbKeyNode = ExprNode::as<RecordKeyNode>(dsqlValue)))
|
else if ((dbKeyNode = ExprNode::as<RecordKeyNode>(dsqlValue)))
|
||||||
dbKeyNode->setParameterName(parameter);
|
dbKeyNode->setParameterName(parameter);
|
||||||
@ -5872,7 +6020,7 @@ void DerivedFieldNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
|||||||
// a set (ORed) of contexts. If any of them are in a valid position the expression is
|
// a set (ORed) of contexts. If any of them are in a valid position the expression is
|
||||||
// evaluated, otherwise a NULL will be returned. This is fix for CORE-1246.
|
// evaluated, otherwise a NULL will be returned. This is fix for CORE-1246.
|
||||||
|
|
||||||
if (dsqlValue->nod_type != Dsql::nod_field &&
|
if (!ExprNode::is<FieldNode>(dsqlValue) &&
|
||||||
!ExprNode::is<DerivedFieldNode>(dsqlValue) &&
|
!ExprNode::is<DerivedFieldNode>(dsqlValue) &&
|
||||||
!ExprNode::is<RecordKeyNode>(dsqlValue) &&
|
!ExprNode::is<RecordKeyNode>(dsqlValue) &&
|
||||||
!ExprNode::is<DsqlMapNode>(dsqlValue))
|
!ExprNode::is<DsqlMapNode>(dsqlValue))
|
||||||
|
@ -437,6 +437,14 @@ public:
|
|||||||
|
|
||||||
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const;
|
||||||
virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
virtual ValueExprNode* dsqlPass(DsqlCompilerScratch* dsqlScratch);
|
||||||
|
|
||||||
|
virtual bool dsqlAggregateFinder(AggregateFinder& visitor);
|
||||||
|
virtual bool dsqlAggregate2Finder(Aggregate2Finder& visitor);
|
||||||
|
virtual bool dsqlInvalidReferenceFinder(InvalidReferenceFinder& visitor);
|
||||||
|
virtual bool dsqlSubSelectFinder(SubSelectFinder& visitor);
|
||||||
|
virtual bool dsqlFieldFinder(FieldFinder& visitor);
|
||||||
|
virtual bool dsqlFieldRemapper(FieldRemapper& visitor);
|
||||||
|
|
||||||
virtual void setParameterName(dsql_par* parameter) const;
|
virtual void setParameterName(dsql_par* parameter) const;
|
||||||
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
virtual void genBlr(DsqlCompilerScratch* dsqlScratch);
|
||||||
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc);
|
||||||
@ -478,6 +486,10 @@ public:
|
|||||||
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
|
virtual dsc* execute(thread_db* tdbb, jrd_req* request) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
dsql_ctx* dsqlContext;
|
||||||
|
dsql_fld* dsqlField;
|
||||||
|
dsql_nod* dsqlIndices;
|
||||||
|
dsc dsqlDesc;
|
||||||
bool byId;
|
bool byId;
|
||||||
USHORT fieldStream;
|
USHORT fieldStream;
|
||||||
USHORT fieldId;
|
USHORT fieldId;
|
||||||
|
@ -67,7 +67,6 @@ static void gen_aggregate(DsqlCompilerScratch*, const dsql_nod*);
|
|||||||
static void gen_coalesce(DsqlCompilerScratch*, const dsql_nod*);
|
static void gen_coalesce(DsqlCompilerScratch*, const dsql_nod*);
|
||||||
static void gen_error_condition(DsqlCompilerScratch*, const dsql_nod*);
|
static void gen_error_condition(DsqlCompilerScratch*, const dsql_nod*);
|
||||||
static void gen_exec_stmt(DsqlCompilerScratch* dsqlScratch, const dsql_nod* node);
|
static void gen_exec_stmt(DsqlCompilerScratch* dsqlScratch, const dsql_nod* node);
|
||||||
static void gen_field(DsqlCompilerScratch*, const dsql_ctx*, const dsql_fld*, dsql_nod*);
|
|
||||||
static void gen_join_rse(DsqlCompilerScratch*, const dsql_nod*);
|
static void gen_join_rse(DsqlCompilerScratch*, const dsql_nod*);
|
||||||
static void gen_map(DsqlCompilerScratch*, dsql_map*);
|
static void gen_map(DsqlCompilerScratch*, dsql_map*);
|
||||||
static inline void gen_optional_expr(DsqlCompilerScratch*, const UCHAR code, dsql_nod*);
|
static inline void gen_optional_expr(DsqlCompilerScratch*, const UCHAR code, dsql_nod*);
|
||||||
@ -182,13 +181,6 @@ void GEN_expr(DsqlCompilerScratch* dsqlScratch, dsql_nod* node)
|
|||||||
dsqlScratch->appendUShort(0); // Field id
|
dsqlScratch->appendUShort(0); // Field id
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
gen_field(dsqlScratch,
|
|
||||||
(dsql_ctx*) node->nod_arg[e_fld_context],
|
|
||||||
(dsql_fld*) node->nod_arg[e_fld_field],
|
|
||||||
node->nod_arg[e_fld_indices]);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case nod_join:
|
case nod_join:
|
||||||
gen_join_rse(dsqlScratch, node);
|
gen_join_rse(dsqlScratch, node);
|
||||||
return;
|
return;
|
||||||
@ -1242,72 +1234,6 @@ static void gen_exec_stmt(DsqlCompilerScratch* dsqlScratch, const dsql_nod* node
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
|
|
||||||
gen_field
|
|
||||||
|
|
||||||
@brief Generate blr for a field - field id's
|
|
||||||
are preferred but not for trigger or view blr.
|
|
||||||
|
|
||||||
|
|
||||||
@param dsqlScratch
|
|
||||||
@param context
|
|
||||||
@param field
|
|
||||||
@param indices
|
|
||||||
|
|
||||||
**/
|
|
||||||
static void gen_field( DsqlCompilerScratch* dsqlScratch, const dsql_ctx* context,
|
|
||||||
const dsql_fld* field, dsql_nod* indices)
|
|
||||||
{
|
|
||||||
// For older clients - generate an error should they try and
|
|
||||||
// access data types which did not exist in the older dialect
|
|
||||||
if (dsqlScratch->clientDialect <= SQL_DIALECT_V5)
|
|
||||||
{
|
|
||||||
switch (field->fld_dtype)
|
|
||||||
{
|
|
||||||
case dtype_sql_date:
|
|
||||||
case dtype_sql_time:
|
|
||||||
case dtype_int64:
|
|
||||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-804) <<
|
|
||||||
Arg::Gds(isc_dsql_datatype_err) <<
|
|
||||||
Arg::Gds(isc_sql_dialect_datatype_unsupport) <<
|
|
||||||
Arg::Num(dsqlScratch->clientDialect) <<
|
|
||||||
Arg::Str(DSC_dtype_tostring(static_cast<UCHAR>(field->fld_dtype))));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// No special action for other data types
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices)
|
|
||||||
dsqlScratch->appendUChar(blr_index);
|
|
||||||
|
|
||||||
if (DDL_ids(dsqlScratch))
|
|
||||||
{
|
|
||||||
dsqlScratch->appendUChar(blr_fid);
|
|
||||||
GEN_stuff_context(dsqlScratch, context);
|
|
||||||
dsqlScratch->appendUShort(field->fld_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dsqlScratch->appendUChar(blr_field);
|
|
||||||
GEN_stuff_context(dsqlScratch, context);
|
|
||||||
dsqlScratch->appendMetaString(field->fld_name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (indices)
|
|
||||||
{
|
|
||||||
dsqlScratch->appendUChar(indices->nod_count);
|
|
||||||
dsql_nod** ptr = indices->nod_arg;
|
|
||||||
for (const dsql_nod* const* end = ptr + indices->nod_count; ptr < end; ptr++)
|
|
||||||
{
|
|
||||||
GEN_expr(dsqlScratch, *ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
||||||
gen_join_rse
|
gen_join_rse
|
||||||
|
@ -422,18 +422,6 @@ void MAKE_desc(DsqlCompilerScratch* dsqlScratch, dsc* desc, dsql_nod* node)
|
|||||||
desc->dsc_flags = 0; // Can first/skip accept NULL in the future?
|
desc->dsc_flags = 0; // Can first/skip accept NULL in the future?
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
if (node->nod_desc.dsc_dtype)
|
|
||||||
{
|
|
||||||
*desc = node->nod_desc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-203) <<
|
|
||||||
Arg::Gds(isc_dsql_field_ref));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case nod_hidden_var:
|
case nod_hidden_var:
|
||||||
MAKE_desc(dsqlScratch, desc, node->nod_arg[e_hidden_var_expr]);
|
MAKE_desc(dsqlScratch, desc, node->nod_arg[e_hidden_var_expr]);
|
||||||
return;
|
return;
|
||||||
@ -541,28 +529,29 @@ dsql_nod* MAKE_field(dsql_ctx* context, dsql_fld* field, dsql_nod* indices)
|
|||||||
DEV_BLKCHK(field, dsql_type_fld);
|
DEV_BLKCHK(field, dsql_type_fld);
|
||||||
DEV_BLKCHK(indices, dsql_type_nod);
|
DEV_BLKCHK(indices, dsql_type_nod);
|
||||||
|
|
||||||
dsql_nod* node = MAKE_node(nod_field, e_fld_count);
|
thread_db* tdbb = JRD_get_thread_data();
|
||||||
node->nod_arg[e_fld_context] = (dsql_nod*) context;
|
FieldNode* node = FB_NEW(*tdbb->getDefaultPool()) FieldNode(*tdbb->getDefaultPool());
|
||||||
node->nod_arg[e_fld_field] = (dsql_nod*) field;
|
node->dsqlContext = context;
|
||||||
|
node->dsqlField = field;
|
||||||
|
|
||||||
if (field->fld_dimensions)
|
if (field->fld_dimensions)
|
||||||
{
|
{
|
||||||
if (indices)
|
if (indices)
|
||||||
{
|
{
|
||||||
node->nod_arg[e_fld_indices] = indices;
|
node->dsqlIndices = indices;
|
||||||
MAKE_desc_from_field(&node->nod_desc, field);
|
MAKE_desc_from_field(&node->dsqlDesc, field);
|
||||||
node->nod_desc.dsc_dtype = static_cast<UCHAR>(field->fld_element_dtype);
|
node->dsqlDesc.dsc_dtype = static_cast<UCHAR>(field->fld_element_dtype);
|
||||||
node->nod_desc.dsc_length = field->fld_element_length;
|
node->dsqlDesc.dsc_length = field->fld_element_length;
|
||||||
|
|
||||||
// node->nod_desc.dsc_scale = field->fld_scale;
|
|
||||||
// node->nod_desc.dsc_sub_type = field->fld_sub_type;
|
|
||||||
|
|
||||||
|
// node->dsqlDesc.dsc_scale = field->fld_scale;
|
||||||
|
// node->dsqlDesc.dsc_sub_type = field->fld_sub_type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
node->nod_desc.dsc_dtype = dtype_array;
|
node->dsqlDesc.dsc_dtype = dtype_array;
|
||||||
node->nod_desc.dsc_length = sizeof(ISC_QUAD);
|
node->dsqlDesc.dsc_length = sizeof(ISC_QUAD);
|
||||||
node->nod_desc.dsc_scale = static_cast<SCHAR>(field->fld_scale);
|
node->dsqlDesc.dsc_scale = static_cast<SCHAR>(field->fld_scale);
|
||||||
node->nod_desc.dsc_sub_type = field->fld_sub_type;
|
node->dsqlDesc.dsc_sub_type = field->fld_sub_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -573,32 +562,33 @@ dsql_nod* MAKE_field(dsql_ctx* context, dsql_fld* field, dsql_nod* indices)
|
|||||||
Arg::Gds(isc_dsql_only_can_subscript_array) << Arg::Str(field->fld_name));
|
Arg::Gds(isc_dsql_only_can_subscript_array) << Arg::Str(field->fld_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
MAKE_desc_from_field(&node->nod_desc, field);
|
MAKE_desc_from_field(&node->dsqlDesc, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((field->fld_flags & FLD_nullable) || (context->ctx_flags & CTX_outer_join))
|
if ((field->fld_flags & FLD_nullable) || (context->ctx_flags & CTX_outer_join))
|
||||||
{
|
node->dsqlDesc.dsc_flags |= DSC_nullable;
|
||||||
node->nod_desc.dsc_flags |= DSC_nullable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNICODE_FSS_HACK
|
// UNICODE_FSS_HACK
|
||||||
// check if the field is a system domain and the type is CHAR/VARCHAR CHARACTER SET UNICODE_FSS
|
// check if the field is a system domain and the type is CHAR/VARCHAR CHARACTER SET UNICODE_FSS
|
||||||
if ((field->fld_flags & FLD_system) && node->nod_desc.dsc_dtype <= dtype_varying &&
|
if ((field->fld_flags & FLD_system) && node->dsqlDesc.dsc_dtype <= dtype_varying &&
|
||||||
INTL_GET_CHARSET(&node->nod_desc) == CS_METADATA)
|
INTL_GET_CHARSET(&node->dsqlDesc) == CS_METADATA)
|
||||||
{
|
{
|
||||||
USHORT adjust = 0;
|
USHORT adjust = 0;
|
||||||
|
|
||||||
if (node->nod_desc.dsc_dtype == dtype_varying)
|
if (node->dsqlDesc.dsc_dtype == dtype_varying)
|
||||||
adjust = sizeof(USHORT);
|
adjust = sizeof(USHORT);
|
||||||
else if (node->nod_desc.dsc_dtype == dtype_cstring)
|
else if (node->dsqlDesc.dsc_dtype == dtype_cstring)
|
||||||
adjust = 1;
|
adjust = 1;
|
||||||
|
|
||||||
node->nod_desc.dsc_length -= adjust;
|
node->dsqlDesc.dsc_length -= adjust;
|
||||||
node->nod_desc.dsc_length *= 3;
|
node->dsqlDesc.dsc_length *= 3;
|
||||||
node->nod_desc.dsc_length += adjust;
|
node->dsqlDesc.dsc_length += adjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
dsql_nod* nod = MAKE_node(nod_class_exprnode, 1);
|
||||||
|
nod->nod_arg[0] = reinterpret_cast<dsql_nod*>(node);
|
||||||
|
|
||||||
|
return nod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -876,7 +866,7 @@ void MAKE_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
|||||||
fb_assert(parameter && item);
|
fb_assert(parameter && item);
|
||||||
|
|
||||||
const char* name_alias = NULL;
|
const char* name_alias = NULL;
|
||||||
const RecordKeyNode* dbKeyNode;
|
const ValueExprNode* exprNode;
|
||||||
|
|
||||||
switch (item->nod_type)
|
switch (item->nod_type)
|
||||||
{
|
{
|
||||||
@ -887,23 +877,15 @@ void MAKE_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
|||||||
exprNode->setParameterName(parameter);
|
exprNode->setParameterName(parameter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case nod_field:
|
|
||||||
field = (dsql_fld*) item->nod_arg[e_fld_field];
|
|
||||||
name_alias = field->fld_name.c_str();
|
|
||||||
context = (dsql_ctx*) item->nod_arg[e_fld_context];
|
|
||||||
break;
|
|
||||||
case nod_alias:
|
case nod_alias:
|
||||||
string = (dsql_str*) item->nod_arg[e_alias_alias];
|
string = (dsql_str*) item->nod_arg[e_alias_alias];
|
||||||
alias = item->nod_arg[e_alias_value];
|
alias = item->nod_arg[e_alias_value];
|
||||||
|
|
||||||
if (alias->nod_type == nod_field)
|
if ((exprNode = ExprNode::as<RecordKeyNode>(alias)) ||
|
||||||
|
(exprNode = ExprNode::as<FieldNode>(alias)))
|
||||||
{
|
{
|
||||||
field = (dsql_fld*) alias->nod_arg[e_fld_field];
|
exprNode->setParameterName(parameter);
|
||||||
parameter->par_name = field->fld_name.c_str();
|
|
||||||
context = (dsql_ctx*) alias->nod_arg[e_fld_context];
|
|
||||||
}
|
}
|
||||||
else if ((dbKeyNode = ExprNode::as<RecordKeyNode>(alias)))
|
|
||||||
dbKeyNode->setParameterName(parameter);
|
|
||||||
|
|
||||||
parameter->par_alias = string->str_data;
|
parameter->par_alias = string->str_data;
|
||||||
break;
|
break;
|
||||||
@ -912,6 +894,7 @@ void MAKE_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
|||||||
case nod_simple_case:
|
case nod_simple_case:
|
||||||
name_alias = "CASE";
|
name_alias = "CASE";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nod_coalesce:
|
case nod_coalesce:
|
||||||
name_alias = "COALESCE";
|
name_alias = "COALESCE";
|
||||||
break;
|
break;
|
||||||
@ -919,20 +902,4 @@ void MAKE_parameter_names(dsql_par* parameter, const dsql_nod* item)
|
|||||||
|
|
||||||
if (name_alias)
|
if (name_alias)
|
||||||
parameter->par_name = parameter->par_alias = name_alias;
|
parameter->par_name = parameter->par_alias = name_alias;
|
||||||
|
|
||||||
if (context)
|
|
||||||
{
|
|
||||||
if (context->ctx_relation)
|
|
||||||
{
|
|
||||||
parameter->par_rel_name = context->ctx_relation->rel_name.c_str();
|
|
||||||
parameter->par_owner_name = context->ctx_relation->rel_owner.c_str();
|
|
||||||
}
|
|
||||||
else if (context->ctx_procedure)
|
|
||||||
{
|
|
||||||
parameter->par_rel_name = context->ctx_procedure->prc_name.identifier.c_str();
|
|
||||||
parameter->par_owner_name = context->ctx_procedure->prc_owner.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter->par_rel_alias = context->ctx_alias;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,6 @@ enum nod_t
|
|||||||
nod_flag,
|
nod_flag,
|
||||||
nod_join,
|
nod_join,
|
||||||
nod_unique,
|
nod_unique,
|
||||||
nod_field,
|
|
||||||
nod_dom_value,
|
nod_dom_value,
|
||||||
nod_field_name,
|
nod_field_name,
|
||||||
nod_alias,
|
nod_alias,
|
||||||
@ -255,11 +254,6 @@ enum node_args {
|
|||||||
e_fpd_list = 0, // nod_for_update
|
e_fpd_list = 0, // nod_for_update
|
||||||
e_fpd_count,
|
e_fpd_count,
|
||||||
|
|
||||||
e_fld_context = 0, // nod_field
|
|
||||||
e_fld_field,
|
|
||||||
e_fld_indices,
|
|
||||||
e_fld_count,
|
|
||||||
|
|
||||||
e_ary_array = 0, // nod_array
|
e_ary_array = 0, // nod_array
|
||||||
e_ary_indices,
|
e_ary_indices,
|
||||||
e_ary_count,
|
e_ary_count,
|
||||||
|
@ -391,14 +391,6 @@ bool AggregateFinder::internalVisit(const dsql_nod* node)
|
|||||||
return aggregate;
|
return aggregate;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_ctx* localContext = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fld_context]);
|
|
||||||
if (deepestLevel < localContext->ctx_scope_level)
|
|
||||||
deepestLevel = localContext->ctx_scope_level;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return visitChildren(node);
|
return visitChildren(node);
|
||||||
}
|
}
|
||||||
@ -452,7 +444,6 @@ bool Aggregate2Finder::internalVisit(const dsql_nod* node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case nod_relation:
|
case nod_relation:
|
||||||
case nod_field:
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -513,36 +504,6 @@ bool FieldFinder::internalVisit(const dsql_nod* node)
|
|||||||
case nod_relation:
|
case nod_relation:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_ctx* field_context = (dsql_ctx*) node->nod_arg[e_fld_context];
|
|
||||||
DEV_BLKCHK(field_context, dsql_type_ctx);
|
|
||||||
|
|
||||||
field = true;
|
|
||||||
|
|
||||||
switch (matchType)
|
|
||||||
{
|
|
||||||
case FIELD_MATCH_TYPE_EQUAL:
|
|
||||||
return field_context->ctx_scope_level == checkScopeLevel;
|
|
||||||
|
|
||||||
case FIELD_MATCH_TYPE_LOWER:
|
|
||||||
return field_context->ctx_scope_level < checkScopeLevel;
|
|
||||||
|
|
||||||
case FIELD_MATCH_TYPE_LOWER_EQUAL:
|
|
||||||
return field_context->ctx_scope_level <= checkScopeLevel;
|
|
||||||
|
|
||||||
///case FIELD_MATCH_TYPE_HIGHER:
|
|
||||||
/// return field_context->ctx_scope_level > checkScopeLevel;
|
|
||||||
|
|
||||||
///case FIELD_MATCH_TYPE_HIGHER_EQUAL:
|
|
||||||
/// return field_context->ctx_scope_level >= checkScopeLevel;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fb_assert(false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return visitChildren(node);
|
return visitChildren(node);
|
||||||
}
|
}
|
||||||
@ -596,28 +557,6 @@ bool InvalidReferenceFinder::internalVisit(const dsql_nod* node)
|
|||||||
invalid |= visit(&node->nod_arg[e_agg_rse]);
|
invalid |= visit(&node->nod_arg[e_agg_rse]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_ctx* localContext = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fld_context]);
|
|
||||||
|
|
||||||
// Wouldn't it be better to call an error from this point where return is true?
|
|
||||||
// Then we could give the fieldname that's making the trouble.
|
|
||||||
|
|
||||||
// If we come here then this field is used inside a aggregate-function. The
|
|
||||||
// ctx_scope_level gives the info how deep the context is inside the statement.
|
|
||||||
|
|
||||||
// If the context-scope-level from this field is lower or the same as the scope-level
|
|
||||||
// from the given context then it is an invalid field.
|
|
||||||
if (localContext->ctx_scope_level == context->ctx_scope_level)
|
|
||||||
{
|
|
||||||
// Return true (invalid) if this field isn't inside the GROUP BY clause, that
|
|
||||||
// should already been seen in the match_node test in that routine start.
|
|
||||||
invalid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nod_coalesce:
|
case nod_coalesce:
|
||||||
///case nod_unique:
|
///case nod_unique:
|
||||||
case nod_rse:
|
case nod_rse:
|
||||||
@ -674,15 +613,6 @@ bool FieldRemapper::internalVisit(dsql_nod* node)
|
|||||||
|
|
||||||
switch (node->nod_type)
|
switch (node->nod_type)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_ctx* localContext = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fld_context]);
|
|
||||||
if (localContext->ctx_scope_level == context->ctx_scope_level)
|
|
||||||
replaceNode(PASS1_post_map(dsqlScratch, node, context, partitionNode, orderNode));
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nod_rse:
|
case nod_rse:
|
||||||
{
|
{
|
||||||
AutoSetRestore<USHORT> autoCurrentLevel(¤tLevel, currentLevel + 1);
|
AutoSetRestore<USHORT> autoCurrentLevel(¤tLevel, currentLevel + 1);
|
||||||
@ -756,7 +686,6 @@ bool SubSelectFinder::internalVisit(const dsql_nod* node)
|
|||||||
|
|
||||||
case nod_aggregate:
|
case nod_aggregate:
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
case nod_relation:
|
case nod_relation:
|
||||||
case nod_field_name:
|
case nod_field_name:
|
||||||
return false;
|
return false;
|
||||||
@ -1116,11 +1045,6 @@ dsql_nod* PASS1_node(DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
return pass1_variable(dsqlScratch, input);
|
return pass1_variable(dsqlScratch, input);
|
||||||
return pass1_field(dsqlScratch, input, false, NULL);
|
return pass1_field(dsqlScratch, input, false, NULL);
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
// AB: nod_field is an already passed node.
|
|
||||||
// This could be done in expand_select_list.
|
|
||||||
return input;
|
|
||||||
|
|
||||||
case nod_array:
|
case nod_array:
|
||||||
if (dsqlScratch->isPsql())
|
if (dsqlScratch->isPsql())
|
||||||
{
|
{
|
||||||
@ -2212,10 +2136,11 @@ static void field_appears_once(const dsql_nod* fields, const dsql_nod* old_field
|
|||||||
if (elem1->nod_type == nod_assign && !is_insert)
|
if (elem1->nod_type == nod_assign && !is_insert)
|
||||||
elem1 = elem1->nod_arg[e_asgn_field];
|
elem1 = elem1->nod_arg[e_asgn_field];
|
||||||
|
|
||||||
if (elem1->nod_type == nod_field)
|
const FieldNode* fieldNode1 = ExprNode::as<FieldNode>(elem1);
|
||||||
|
|
||||||
|
if (fieldNode1)
|
||||||
{
|
{
|
||||||
const Firebird::MetaName& n1 =
|
const Firebird::MetaName& n1 = fieldNode1->dsqlField->fld_name;
|
||||||
reinterpret_cast<dsql_fld*>(elem1->nod_arg[e_fld_field])->fld_name;
|
|
||||||
|
|
||||||
for (int j = i + 1; j < fields->nod_count; ++j)
|
for (int j = i + 1; j < fields->nod_count; ++j)
|
||||||
{
|
{
|
||||||
@ -2223,18 +2148,19 @@ static void field_appears_once(const dsql_nod* fields, const dsql_nod* old_field
|
|||||||
if (elem2->nod_type == nod_assign && !is_insert)
|
if (elem2->nod_type == nod_assign && !is_insert)
|
||||||
elem2 = elem2->nod_arg[e_asgn_field];
|
elem2 = elem2->nod_arg[e_asgn_field];
|
||||||
|
|
||||||
if (elem2->nod_type == nod_field)
|
const FieldNode* fieldNode2 = ExprNode::as<FieldNode>(elem2);
|
||||||
|
|
||||||
|
if (fieldNode2)
|
||||||
{
|
{
|
||||||
const Firebird::MetaName& n2 =
|
const Firebird::MetaName& n2 = fieldNode2->dsqlField->fld_name;
|
||||||
reinterpret_cast<dsql_fld*>(elem2->nod_arg[e_fld_field])->fld_name;
|
|
||||||
|
|
||||||
if (n1 == n2)
|
if (n1 == n2)
|
||||||
{
|
{
|
||||||
const dsql_ctx* tmp_ctx = (dsql_ctx*) elem2->nod_arg[e_fld_context];
|
const dsql_ctx* tmp_ctx = fieldNode2->dsqlContext;
|
||||||
const dsql_rel* bad_rel = tmp_ctx ? tmp_ctx->ctx_relation : 0;
|
const dsql_rel* bad_rel = tmp_ctx ? tmp_ctx->ctx_relation : 0;
|
||||||
field_duplication(bad_rel ? bad_rel->rel_name.c_str() : 0,
|
field_duplication((bad_rel ? bad_rel->rel_name.c_str() : 0),
|
||||||
n2.c_str(),
|
n2.c_str(),
|
||||||
is_insert ? old_fields->nod_arg[j]: old_fields->nod_arg[j]->nod_arg[1],
|
(is_insert ? old_fields->nod_arg[j] : old_fields->nod_arg[j]->nod_arg[1]),
|
||||||
dsqlScratch);
|
dsqlScratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2585,19 +2511,6 @@ bool PASS1_node_match(const dsql_nod* node1, const dsql_nod* node2, bool ignore_
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
if (node1->nod_arg[e_fld_field] != node2->nod_arg[e_fld_field] ||
|
|
||||||
node1->nod_arg[e_fld_context] != node2->nod_arg[e_fld_context])
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (node1->nod_arg[e_fld_indices] || node2->nod_arg[e_fld_indices])
|
|
||||||
{
|
|
||||||
return PASS1_node_match(node1->nod_arg[e_fld_indices],
|
|
||||||
node2->nod_arg[e_fld_indices], ignore_map_cast);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case nod_derived_table:
|
case nod_derived_table:
|
||||||
{
|
{
|
||||||
const dsql_ctx* ctx1 = (dsql_ctx*) node1->nod_arg[e_derived_table_context];
|
const dsql_ctx* ctx1 = (dsql_ctx*) node1->nod_arg[e_derived_table_context];
|
||||||
@ -2735,8 +2648,10 @@ static void pass1_blob( DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
thread_db* tdbb = JRD_get_thread_data();
|
thread_db* tdbb = JRD_get_thread_data();
|
||||||
|
|
||||||
PASS1_make_context(dsqlScratch, input->nod_arg[e_blb_relation]);
|
PASS1_make_context(dsqlScratch, input->nod_arg[e_blb_relation]);
|
||||||
dsql_nod* field = pass1_field(dsqlScratch, input->nod_arg[e_blb_field], false, NULL);
|
FieldNode* field = ExprNode::as<FieldNode>(
|
||||||
if (field->nod_desc.dsc_dtype != dtype_blob)
|
pass1_field(dsqlScratch, input->nod_arg[e_blb_field], false, NULL));
|
||||||
|
|
||||||
|
if (field->dsqlDesc.dsc_dtype != dtype_blob)
|
||||||
{
|
{
|
||||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-206) <<
|
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-206) <<
|
||||||
Arg::Gds(isc_dsql_blob_err));
|
Arg::Gds(isc_dsql_blob_err));
|
||||||
@ -2758,8 +2673,8 @@ static void pass1_blob( DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
blob->blb_segment = parameter;
|
blob->blb_segment = parameter;
|
||||||
parameter->par_desc.dsc_dtype = dtype_text;
|
parameter->par_desc.dsc_dtype = dtype_text;
|
||||||
parameter->par_desc.dsc_ttype() = ttype_binary;
|
parameter->par_desc.dsc_ttype() = ttype_binary;
|
||||||
parameter->par_desc.dsc_length = ((dsql_fld*) field->nod_arg[e_fld_field])->fld_seg_length;
|
parameter->par_desc.dsc_length = field->dsqlField->fld_seg_length;
|
||||||
DEV_BLKCHK(field->nod_arg[e_fld_field], dsql_type_fld);
|
DEV_BLKCHK(field->dsqlField, dsql_type_fld);
|
||||||
|
|
||||||
// The Null indicator is used to pass back the segment length,
|
// The Null indicator is used to pass back the segment length,
|
||||||
// set DSC_nullable so that the SQL_type is set to SQL_TEXT+1 instead
|
// set DSC_nullable so that the SQL_type is set to SQL_TEXT+1 instead
|
||||||
@ -2773,7 +2688,7 @@ static void pass1_blob( DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
dsql_msg* temp_msg = (input->nod_type == nod_get_segment) ?
|
dsql_msg* temp_msg = (input->nod_type == nod_get_segment) ?
|
||||||
blob->blb_open_in_msg : blob->blb_open_out_msg;
|
blob->blb_open_in_msg : blob->blb_open_out_msg;
|
||||||
blob->blb_blob_id = parameter = MAKE_parameter(temp_msg, true, true, 0, NULL);
|
blob->blb_blob_id = parameter = MAKE_parameter(temp_msg, true, true, 0, NULL);
|
||||||
MAKE_desc(dsqlScratch, ¶meter->par_desc, field);
|
field->make(dsqlScratch, ¶meter->par_desc);
|
||||||
parameter->par_desc.dsc_dtype = dtype_quad;
|
parameter->par_desc.dsc_dtype = dtype_quad;
|
||||||
parameter->par_desc.dsc_scale = 0;
|
parameter->par_desc.dsc_scale = 0;
|
||||||
|
|
||||||
@ -4243,12 +4158,8 @@ static dsql_nod* pass1_group_by_list(DsqlCompilerScratch* dsqlScratch, dsql_nod*
|
|||||||
static dsql_nod* pass1_hidden_variable(DsqlCompilerScratch* dsqlScratch, dsql_nod*& expr)
|
static dsql_nod* pass1_hidden_variable(DsqlCompilerScratch* dsqlScratch, dsql_nod*& expr)
|
||||||
{
|
{
|
||||||
// For some node types, it's better to not create temporary value.
|
// For some node types, it's better to not create temporary value.
|
||||||
switch (expr->nod_type)
|
if (expr->nod_type == nod_class_exprnode)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
case nod_class_exprnode:
|
|
||||||
switch (ExprNode::fromLegacy(expr)->type)
|
switch (ExprNode::fromLegacy(expr)->type)
|
||||||
{
|
{
|
||||||
case ExprNode::TYPE_CURRENT_DATE:
|
case ExprNode::TYPE_CURRENT_DATE:
|
||||||
@ -4256,6 +4167,7 @@ static dsql_nod* pass1_hidden_variable(DsqlCompilerScratch* dsqlScratch, dsql_no
|
|||||||
case ExprNode::TYPE_CURRENT_TIMESTAMP:
|
case ExprNode::TYPE_CURRENT_TIMESTAMP:
|
||||||
case ExprNode::TYPE_CURRENT_ROLE:
|
case ExprNode::TYPE_CURRENT_ROLE:
|
||||||
case ExprNode::TYPE_CURRENT_USER:
|
case ExprNode::TYPE_CURRENT_USER:
|
||||||
|
case ExprNode::TYPE_FIELD:
|
||||||
case ExprNode::TYPE_INTERNAL_INFO:
|
case ExprNode::TYPE_INTERNAL_INFO:
|
||||||
case ExprNode::TYPE_LITERAL:
|
case ExprNode::TYPE_LITERAL:
|
||||||
case ExprNode::TYPE_NULL:
|
case ExprNode::TYPE_NULL:
|
||||||
@ -4264,7 +4176,6 @@ static dsql_nod* pass1_hidden_variable(DsqlCompilerScratch* dsqlScratch, dsql_no
|
|||||||
case ExprNode::TYPE_VARIABLE:
|
case ExprNode::TYPE_VARIABLE:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VariableNode* var = MAKE_variable(NULL, "", VAR_local, 0, 0, dsqlScratch->hiddenVarsNumber++);
|
VariableNode* var = MAKE_variable(NULL, "", VAR_local, 0, 0, dsqlScratch->hiddenVarsNumber++);
|
||||||
@ -4349,13 +4260,14 @@ static dsql_nod* pass1_insert( DsqlCompilerScratch* dsqlScratch, dsql_nod* input
|
|||||||
|
|
||||||
const dsql_ctx* tmp_ctx = NULL;
|
const dsql_ctx* tmp_ctx = NULL;
|
||||||
const TEXT* tmp_name = NULL;
|
const TEXT* tmp_name = NULL;
|
||||||
|
const FieldNode* fieldNode;
|
||||||
const DerivedFieldNode* derivedField;
|
const DerivedFieldNode* derivedField;
|
||||||
|
|
||||||
if (temp2->nod_type == nod_field)
|
if ((fieldNode = ExprNode::as<FieldNode>(temp2)))
|
||||||
{
|
{
|
||||||
tmp_ctx = (dsql_ctx*) temp2->nod_arg[e_fld_context];
|
tmp_ctx = fieldNode->dsqlContext;
|
||||||
tmp_name = (temp2->nod_arg[e_fld_field] ?
|
if (fieldNode->dsqlField)
|
||||||
((dsql_fld*) temp2->nod_arg[e_fld_field])->fld_name.c_str() : NULL);
|
tmp_name = fieldNode->dsqlField->fld_name.c_str();
|
||||||
}
|
}
|
||||||
else if ((derivedField = ExprNode::as<DerivedFieldNode>(temp2)))
|
else if ((derivedField = ExprNode::as<DerivedFieldNode>(temp2)))
|
||||||
{
|
{
|
||||||
@ -4543,6 +4455,7 @@ static dsql_nod* pass1_join(DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
{
|
{
|
||||||
const TEXT* name = NULL;
|
const TEXT* name = NULL;
|
||||||
dsql_nod* item = j.object();
|
dsql_nod* item = j.object();
|
||||||
|
FieldNode* fieldNode;
|
||||||
DerivedFieldNode* derivedField;
|
DerivedFieldNode* derivedField;
|
||||||
|
|
||||||
switch (item->nod_type)
|
switch (item->nod_type)
|
||||||
@ -4551,12 +4464,10 @@ static dsql_nod* pass1_join(DsqlCompilerScratch* dsqlScratch, dsql_nod* input)
|
|||||||
name = reinterpret_cast<dsql_str*>(item->nod_arg[e_alias_alias])->str_data;
|
name = reinterpret_cast<dsql_str*>(item->nod_arg[e_alias_alias])->str_data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
name = reinterpret_cast<dsql_fld*>(item->nod_arg[e_fld_field])->fld_name.c_str();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((derivedField = ExprNode::as<DerivedFieldNode>(item)))
|
if ((fieldNode = ExprNode::as<FieldNode>(item)))
|
||||||
|
name = fieldNode->dsqlField->fld_name.c_str();
|
||||||
|
else if ((derivedField = ExprNode::as<DerivedFieldNode>(item)))
|
||||||
name = derivedField->name.c_str();
|
name = derivedField->name.c_str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4865,6 +4776,7 @@ static dsql_nod* pass1_lookup_alias(DsqlCompilerScratch* dsqlScratch, const dsql
|
|||||||
{
|
{
|
||||||
dsql_nod* matchingNode = NULL;
|
dsql_nod* matchingNode = NULL;
|
||||||
dsql_nod* node = *ptr;
|
dsql_nod* node = *ptr;
|
||||||
|
FieldNode* fieldNode;
|
||||||
DerivedFieldNode* derivedField;
|
DerivedFieldNode* derivedField;
|
||||||
|
|
||||||
switch (node->nod_type)
|
switch (node->nod_type)
|
||||||
@ -4878,16 +4790,13 @@ static dsql_nod* pass1_lookup_alias(DsqlCompilerScratch* dsqlScratch, const dsql
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nod_field:
|
default:
|
||||||
|
if ((fieldNode = ExprNode::as<FieldNode>(node)))
|
||||||
{
|
{
|
||||||
const dsql_fld* field = (dsql_fld*) node->nod_arg[e_fld_field];
|
if (fieldNode->dsqlField->fld_name == name->str_data)
|
||||||
if (field->fld_name == name->str_data)
|
|
||||||
matchingNode = node;
|
matchingNode = node;
|
||||||
}
|
}
|
||||||
break;
|
else if ((derivedField = ExprNode::as<DerivedFieldNode>(node)))
|
||||||
|
|
||||||
default:
|
|
||||||
if ((derivedField = ExprNode::as<DerivedFieldNode>(node)))
|
|
||||||
{
|
{
|
||||||
if (strcmp(derivedField->name.c_str(), name->str_data) == 0)
|
if (strcmp(derivedField->name.c_str(), name->str_data) == 0)
|
||||||
matchingNode = node;
|
matchingNode = node;
|
||||||
@ -4907,16 +4816,14 @@ static dsql_nod* pass1_lookup_alias(DsqlCompilerScratch* dsqlScratch, const dsql
|
|||||||
buffer1[0] = 0;
|
buffer1[0] = 0;
|
||||||
switch (returnNode->nod_type)
|
switch (returnNode->nod_type)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
strcat(buffer1, "a field");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nod_alias:
|
case nod_alias:
|
||||||
strcat(buffer1, "an alias");
|
strcat(buffer1, "an alias");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((derivedField = ExprNode::as<DerivedFieldNode>(returnNode)))
|
if (ExprNode::is<FieldNode>(returnNode))
|
||||||
|
strcat(buffer1, "a field");
|
||||||
|
else if (ExprNode::is<DerivedFieldNode>(returnNode))
|
||||||
strcat(buffer1, "a derived field");
|
strcat(buffer1, "a derived field");
|
||||||
else
|
else
|
||||||
strcat(buffer1, "an item");
|
strcat(buffer1, "an item");
|
||||||
@ -4928,16 +4835,14 @@ static dsql_nod* pass1_lookup_alias(DsqlCompilerScratch* dsqlScratch, const dsql
|
|||||||
|
|
||||||
switch (matchingNode->nod_type)
|
switch (matchingNode->nod_type)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
strcat(buffer2, "a field");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nod_alias:
|
case nod_alias:
|
||||||
strcat(buffer2, "an alias");
|
strcat(buffer2, "an alias");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((derivedField = ExprNode::as<DerivedFieldNode>(matchingNode)))
|
if (ExprNode::is<FieldNode>(matchingNode))
|
||||||
|
strcat(buffer2, "a field");
|
||||||
|
else if (ExprNode::is<DerivedFieldNode>(matchingNode))
|
||||||
strcat(buffer2, "a derived field");
|
strcat(buffer2, "a derived field");
|
||||||
else
|
else
|
||||||
strcat(buffer2, "an item");
|
strcat(buffer2, "an item");
|
||||||
@ -4980,23 +4885,6 @@ static dsql_nod* pass1_make_derived_field(DsqlCompilerScratch* dsqlScratch, thre
|
|||||||
|
|
||||||
switch (select_item->nod_type)
|
switch (select_item->nod_type)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_fld* field = (dsql_fld*) select_item->nod_arg[e_fld_field];
|
|
||||||
DEV_BLKCHK(field, dsql_type_fld);
|
|
||||||
|
|
||||||
// Create a derived field and hook in.
|
|
||||||
|
|
||||||
DerivedFieldNode* newField = FB_NEW(pool) DerivedFieldNode(pool, field->fld_name,
|
|
||||||
dsqlScratch->scopeLevel, select_item);
|
|
||||||
|
|
||||||
dsql_nod* nod = MAKE_node(nod_class_exprnode, 1);
|
|
||||||
nod->nod_arg[0] = reinterpret_cast<dsql_nod*>(newField);
|
|
||||||
nod->nod_desc = select_item->nod_desc;
|
|
||||||
|
|
||||||
return nod;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nod_alias:
|
case nod_alias:
|
||||||
{
|
{
|
||||||
const dsql_str* alias_alias = (dsql_str*) select_item->nod_arg[e_alias_alias];
|
const dsql_str* alias_alias = (dsql_str*) select_item->nod_arg[e_alias_alias];
|
||||||
@ -5017,6 +4905,7 @@ static dsql_nod* pass1_make_derived_field(DsqlCompilerScratch* dsqlScratch, thre
|
|||||||
{
|
{
|
||||||
SubQueryNode* subQueryNode;
|
SubQueryNode* subQueryNode;
|
||||||
DsqlMapNode* mapNode;
|
DsqlMapNode* mapNode;
|
||||||
|
FieldNode* fieldNode;
|
||||||
DerivedFieldNode* derivedField;
|
DerivedFieldNode* derivedField;
|
||||||
|
|
||||||
if ((subQueryNode = ExprNode::as<SubQueryNode>(select_item)))
|
if ((subQueryNode = ExprNode::as<SubQueryNode>(select_item)))
|
||||||
@ -5045,6 +4934,19 @@ static dsql_nod* pass1_make_derived_field(DsqlCompilerScratch* dsqlScratch, thre
|
|||||||
return derived_field;
|
return derived_field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((fieldNode = ExprNode::as<FieldNode>(select_item)))
|
||||||
|
{
|
||||||
|
// Create a derived field and hook in.
|
||||||
|
|
||||||
|
DerivedFieldNode* newField = FB_NEW(pool) DerivedFieldNode(pool,
|
||||||
|
fieldNode->dsqlField->fld_name, dsqlScratch->scopeLevel, select_item);
|
||||||
|
|
||||||
|
dsql_nod* nod = MAKE_node(nod_class_exprnode, 1);
|
||||||
|
nod->nod_arg[0] = reinterpret_cast<dsql_nod*>(newField);
|
||||||
|
nod->nod_desc = fieldNode->dsqlDesc;
|
||||||
|
|
||||||
|
return nod;
|
||||||
|
}
|
||||||
else if ((derivedField = ExprNode::as<DerivedFieldNode>(select_item)))
|
else if ((derivedField = ExprNode::as<DerivedFieldNode>(select_item)))
|
||||||
{
|
{
|
||||||
// Create a derived field that points to a derived field.
|
// Create a derived field that points to a derived field.
|
||||||
@ -7086,16 +6988,17 @@ static void pass1_union_auto_cast(DsqlCompilerScratch* dsqlScratch, dsql_nod* in
|
|||||||
name_node = mapNode->map->map_node;
|
name_node = mapNode->map->map_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name_node->nod_type == nod_field)
|
const FieldNode* fieldNode;
|
||||||
|
|
||||||
|
if ((fieldNode = ExprNode::as<FieldNode>(name_node)))
|
||||||
{
|
{
|
||||||
dsql_fld* sub_field = (dsql_fld*) name_node->nod_arg[e_fld_field];
|
|
||||||
// Create new node for alias and copy fieldname
|
// Create new node for alias and copy fieldname
|
||||||
alias_node = MAKE_node(nod_alias, e_alias_count);
|
alias_node = MAKE_node(nod_alias, e_alias_count);
|
||||||
// Copy fieldname to a new string.
|
// Copy fieldname to a new string.
|
||||||
dsql_str* str_alias = FB_NEW_RPT(*tdbb->getDefaultPool(),
|
dsql_str* str_alias = FB_NEW_RPT(*tdbb->getDefaultPool(),
|
||||||
sub_field->fld_name.length()) dsql_str;
|
fieldNode->dsqlField->fld_name.length()) dsql_str;
|
||||||
strcpy(str_alias->str_data, sub_field->fld_name.c_str());
|
strcpy(str_alias->str_data, fieldNode->dsqlField->fld_name.c_str());
|
||||||
str_alias->str_length = sub_field->fld_name.length();
|
str_alias->str_length = fieldNode->dsqlField->fld_name.length();
|
||||||
alias_node->nod_arg[e_alias_alias] = (dsql_nod*) str_alias;
|
alias_node->nod_arg[e_alias_alias] = (dsql_nod*) str_alias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7965,24 +7868,27 @@ static dsql_nod* resolve_using_field(DsqlCompilerScratch* dsqlScratch, dsql_str*
|
|||||||
PASS1_field_unknown(qualifier.c_str(), name->str_data, flawedNode);
|
PASS1_field_unknown(qualifier.c_str(), name->str_data, flawedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FieldNode* fieldNode;
|
||||||
DerivedFieldNode* derivedField;
|
DerivedFieldNode* derivedField;
|
||||||
|
|
||||||
if ((derivedField = ExprNode::as<DerivedFieldNode>(node)))
|
if ((fieldNode = ExprNode::as<FieldNode>(node)))
|
||||||
|
{
|
||||||
|
ctx = fieldNode->dsqlContext;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
else if ((derivedField = ExprNode::as<DerivedFieldNode>(node)))
|
||||||
{
|
{
|
||||||
ctx = derivedField->context;
|
ctx = derivedField->context;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (node->nod_type)
|
if (node->nod_type == nod_alias)
|
||||||
{
|
{
|
||||||
case nod_field:
|
|
||||||
ctx = reinterpret_cast<dsql_ctx*>(node->nod_arg[e_fln_context]);
|
|
||||||
break;
|
|
||||||
case nod_alias:
|
|
||||||
fb_assert(node->nod_count >= (int) e_alias_imp_join - 1);
|
fb_assert(node->nod_count >= (int) e_alias_imp_join - 1);
|
||||||
ctx = reinterpret_cast<ImplicitJoin*>(node->nod_arg[e_alias_imp_join])->visibleInContext;
|
ctx = reinterpret_cast<ImplicitJoin*>(node->nod_arg[e_alias_imp_join])->visibleInContext;
|
||||||
break;
|
}
|
||||||
default:
|
else
|
||||||
|
{
|
||||||
fb_assert(false);
|
fb_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8107,10 +8013,10 @@ static void set_parameter_name( dsql_nod* par_node, const dsql_nod* fld_node, co
|
|||||||
if (!par_node)
|
if (!par_node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Could it be something else ???
|
const FieldNode* fieldNode = ExprNode::as<FieldNode>(fld_node);
|
||||||
fb_assert(fld_node->nod_type == nod_field);
|
fb_assert(fieldNode); // Could it be something else ???
|
||||||
|
|
||||||
if (fld_node->nod_desc.dsc_dtype != dtype_array)
|
if (fieldNode->dsqlDesc.dsc_dtype != dtype_array)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (par_node->nod_type)
|
switch (par_node->nod_type)
|
||||||
@ -8141,9 +8047,7 @@ static void set_parameter_name( dsql_nod* par_node, const dsql_nod* fld_node, co
|
|||||||
{
|
{
|
||||||
ParameterNode* paramNode = exprNode->as<ParameterNode>();
|
ParameterNode* paramNode = exprNode->as<ParameterNode>();
|
||||||
dsql_par* parameter = paramNode->dsqlParameter;
|
dsql_par* parameter = paramNode->dsqlParameter;
|
||||||
const dsql_fld* field = (dsql_fld*) fld_node->nod_arg[e_fld_field];
|
parameter->par_name = fieldNode->dsqlField->fld_name.c_str();
|
||||||
DEV_BLKCHK(field, dsql_type_fld);
|
|
||||||
parameter->par_name = field->fld_name.c_str();
|
|
||||||
parameter->par_rel_name = relation->rel_name.c_str();
|
parameter->par_rel_name = relation->rel_name.c_str();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -8790,20 +8694,6 @@ void DSQL_pretty(const dsql_nod* node, int column)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nod_field:
|
|
||||||
{
|
|
||||||
const dsql_ctx* context = (dsql_ctx*) node->nod_arg[e_fld_context];
|
|
||||||
const dsql_rel* relation = context->ctx_relation;
|
|
||||||
const dsql_prc* procedure = context->ctx_procedure;
|
|
||||||
const dsql_fld* field = (dsql_fld*) node->nod_arg[e_fld_field];
|
|
||||||
trace_line("%sfield %s.%s, context %d\n", buffer,
|
|
||||||
(relation != NULL ?
|
|
||||||
relation->rel_name.c_str() :
|
|
||||||
(procedure != NULL ? procedure->prc_name.toString().c_str() : "unknown_db_object")),
|
|
||||||
field->fld_name.c_str(), context->ctx_context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nod_field_name:
|
case nod_field_name:
|
||||||
trace_line("%sfield name: \"", buffer);
|
trace_line("%sfield name: \"", buffer);
|
||||||
string = (dsql_str*) node->nod_arg[e_fln_context];
|
string = (dsql_str*) node->nod_arg[e_fln_context];
|
||||||
|
Loading…
Reference in New Issue
Block a user