From: <asf...@us...> - 2010-12-19 21:42:40
|
Revision: 52061 http://firebird.svn.sourceforge.net/firebird/?rev=52061&view=rev Author: asfernandes Date: 2010-12-19 21:42:32 +0000 (Sun, 19 Dec 2010) Log Message: ----------- Refactor DSQL's nod_field Modified Paths: -------------- firebird/trunk/src/dsql/DdlNodes.epp firebird/trunk/src/dsql/ExprNodes.cpp firebird/trunk/src/dsql/ExprNodes.h firebird/trunk/src/dsql/gen.cpp firebird/trunk/src/dsql/make.cpp firebird/trunk/src/dsql/node.h firebird/trunk/src/dsql/pass1.cpp Modified: firebird/trunk/src/dsql/DdlNodes.epp =================================================================== --- firebird/trunk/src/dsql/DdlNodes.epp 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/DdlNodes.epp 2010-12-19 21:42:32 UTC (rev 52061) @@ -7392,9 +7392,10 @@ } const dsql_fld* nameField = NULL; + const FieldNode* fieldNameNode = ExprNode::as<FieldNode>(nameNode); - if (nameNode->nod_type == Dsql::nod_field) - nameField = (dsql_fld*) nameNode->nod_arg[Dsql::e_fld_field]; + if (fieldNameNode) + nameField = fieldNameNode->dsqlField; const TEXT* fieldStr = NULL; @@ -7411,10 +7412,12 @@ dsql_fld* field = 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]; - context = (dsql_ctx*) fieldNode->nod_arg[Dsql::e_fld_context]; + field = fieldNameNode->dsqlField; + context = fieldNameNode->dsqlContext; } else updatable = false; @@ -8064,8 +8067,8 @@ if (replaceFields) replaceName = (dsql_str*) (*replace)->nod_arg[Dsql::e_fln_name]; - const dsql_nod* fieldNode = *search; - const dsql_fld* field = (dsql_fld*) fieldNode->nod_arg[Dsql::e_fld_field]; + const FieldNode* fieldNode = ExprNode::as<FieldNode>(*search); + const dsql_fld* field = fieldNode->dsqlField; if (field->fld_name == fieldName->str_data) { Modified: firebird/trunk/src/dsql/ExprNodes.cpp =================================================================== --- firebird/trunk/src/dsql/ExprNodes.cpp 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/ExprNodes.cpp 2010-12-19 21:42:32 UTC (rev 52061) @@ -4202,12 +4202,16 @@ FieldNode::FieldNode(MemoryPool& pool) : TypedNode<ValueExprNode, ExprNode::TYPE_FIELD>(pool), + dsqlContext(NULL), + dsqlField(NULL), + dsqlIndices(NULL), byId(false), fieldStream(0), fieldId(0), format(NULL), defaultValue(NULL) { + dsqlDesc.clear(); } // Parse a field. @@ -4383,40 +4387,191 @@ ExprNode::print(text, nodes); } -//// TODO: Implement FieldNode DSQL support. - ValueExprNode* FieldNode::dsqlPass(DsqlCompilerScratch* dsqlScratch) { - fb_assert(false); - return NULL; + // 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); + } + + 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 { - 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) { - 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) { - 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 { - fb_assert(false); - return false; + if (!ExprNode::dsqlMatch(other, ignoreMapCast)) + 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, USHORT stream) /*const*/ { const FieldNode* o = other->as<FieldNode>(); - // ASF: Why not test fieldStream == o->fieldStream? return o && fieldId == o->fieldId && o->fieldStream == stream; } @@ -5626,30 +5781,17 @@ } const char* nameAlias = NULL; - const dsql_ctx* context = NULL; - const dsql_fld* field; + const FieldNode* fieldNode = NULL; const dsql_nod* alias; const dsql_str* str; 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: str = (dsql_str*) nestNode->nod_arg[Dsql::e_alias_alias]; parameter->par_alias = str->str_data; alias = nestNode->nod_arg[Dsql::e_alias_value]; - - 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]; - } + fieldNode = ExprNode::as<FieldNode>(alias); break; case Dsql::nod_class_exprnode: @@ -5668,19 +5810,25 @@ { parameter->par_alias = derivedField->name; alias = derivedField->dsqlValue; - - 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]; - } + fieldNode = ExprNode::as<FieldNode>(alias); } + else if ((fieldNode = ExprNode::as<FieldNode>(nestNode))) + nameAlias = fieldNode->dsqlField->fld_name.c_str(); break; } } // 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) parameter->par_name = parameter->par_alias = nameAlias; @@ -5836,13 +5984,13 @@ void DerivedFieldNode::setParameterName(dsql_par* parameter) const { const dsql_ctx* context = NULL; + const FieldNode* fieldNode; 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 = field->fld_name.c_str(); - context = (dsql_ctx*) dsqlValue->nod_arg[Dsql::e_fld_context]; + parameter->par_name = fieldNode->dsqlField->fld_name.c_str(); + context = fieldNode->dsqlContext; } else if ((dbKeyNode = ExprNode::as<RecordKeyNode>(dsqlValue))) dbKeyNode->setParameterName(parameter); @@ -5872,7 +6020,7 @@ // 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. - if (dsqlValue->nod_type != Dsql::nod_field && + if (!ExprNode::is<FieldNode>(dsqlValue) && !ExprNode::is<DerivedFieldNode>(dsqlValue) && !ExprNode::is<RecordKeyNode>(dsqlValue) && !ExprNode::is<DsqlMapNode>(dsqlValue)) Modified: firebird/trunk/src/dsql/ExprNodes.h =================================================================== --- firebird/trunk/src/dsql/ExprNodes.h 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/ExprNodes.h 2010-12-19 21:42:32 UTC (rev 52061) @@ -437,6 +437,14 @@ virtual void print(Firebird::string& text, Firebird::Array<dsql_nod*>& nodes) const; 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 genBlr(DsqlCompilerScratch* dsqlScratch); virtual void make(DsqlCompilerScratch* dsqlScratch, dsc* desc); @@ -478,6 +486,10 @@ virtual dsc* execute(thread_db* tdbb, jrd_req* request) const; public: + dsql_ctx* dsqlContext; + dsql_fld* dsqlField; + dsql_nod* dsqlIndices; + dsc dsqlDesc; bool byId; USHORT fieldStream; USHORT fieldId; Modified: firebird/trunk/src/dsql/gen.cpp =================================================================== --- firebird/trunk/src/dsql/gen.cpp 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/gen.cpp 2010-12-19 21:42:32 UTC (rev 52061) @@ -67,7 +67,6 @@ static void gen_coalesce(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_field(DsqlCompilerScratch*, const dsql_ctx*, const dsql_fld*, dsql_nod*); static void gen_join_rse(DsqlCompilerScratch*, const dsql_nod*); static void gen_map(DsqlCompilerScratch*, dsql_map*); static inline void gen_optional_expr(DsqlCompilerScratch*, const UCHAR code, dsql_nod*); @@ -182,13 +181,6 @@ dsqlScratch->appendUShort(0); // Field id 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: gen_join_rse(dsqlScratch, node); return; @@ -1244,72 +1236,6 @@ /** - 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 @brief Generate a record selection expression Modified: firebird/trunk/src/dsql/make.cpp =================================================================== --- firebird/trunk/src/dsql/make.cpp 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/make.cpp 2010-12-19 21:42:32 UTC (rev 52061) @@ -422,18 +422,6 @@ desc->dsc_flags = 0; // Can first/skip accept NULL in the future? 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: MAKE_desc(dsqlScratch, desc, node->nod_arg[e_hidden_var_expr]); return; @@ -541,28 +529,29 @@ DEV_BLKCHK(field, dsql_type_fld); DEV_BLKCHK(indices, dsql_type_nod); - dsql_nod* node = MAKE_node(nod_field, e_fld_count); - node->nod_arg[e_fld_context] = (dsql_nod*) context; - node->nod_arg[e_fld_field] = (dsql_nod*) field; + thread_db* tdbb = JRD_get_thread_data(); + FieldNode* node = FB_NEW(*tdbb->getDefaultPool()) FieldNode(*tdbb->getDefaultPool()); + node->dsqlContext = context; + node->dsqlField = field; + if (field->fld_dimensions) { if (indices) { - node->nod_arg[e_fld_indices] = indices; - MAKE_desc_from_field(&node->nod_desc, field); - node->nod_desc.dsc_dtype = static_cast<UCHAR>(field->fld_element_dtype); - node->nod_desc.dsc_length = field->fld_element_length; + node->dsqlIndices = indices; + MAKE_desc_from_field(&node->dsqlDesc, field); + node->dsqlDesc.dsc_dtype = static_cast<UCHAR>(field->fld_element_dtype); + 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 { - node->nod_desc.dsc_dtype = dtype_array; - node->nod_desc.dsc_length = sizeof(ISC_QUAD); - node->nod_desc.dsc_scale = static_cast<SCHAR>(field->fld_scale); - node->nod_desc.dsc_sub_type = field->fld_sub_type; + node->dsqlDesc.dsc_dtype = dtype_array; + node->dsqlDesc.dsc_length = sizeof(ISC_QUAD); + node->dsqlDesc.dsc_scale = static_cast<SCHAR>(field->fld_scale); + node->dsqlDesc.dsc_sub_type = field->fld_sub_type; } } else @@ -573,32 +562,33 @@ 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)) - { - node->nod_desc.dsc_flags |= DSC_nullable; - } + node->dsqlDesc.dsc_flags |= DSC_nullable; // UNICODE_FSS_HACK // 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 && - INTL_GET_CHARSET(&node->nod_desc) == CS_METADATA) + if ((field->fld_flags & FLD_system) && node->dsqlDesc.dsc_dtype <= dtype_varying && + INTL_GET_CHARSET(&node->dsqlDesc) == CS_METADATA) { USHORT adjust = 0; - if (node->nod_desc.dsc_dtype == dtype_varying) + if (node->dsqlDesc.dsc_dtype == dtype_varying) adjust = sizeof(USHORT); - else if (node->nod_desc.dsc_dtype == dtype_cstring) + else if (node->dsqlDesc.dsc_dtype == dtype_cstring) adjust = 1; - node->nod_desc.dsc_length -= adjust; - node->nod_desc.dsc_length *= 3; - node->nod_desc.dsc_length += adjust; + node->dsqlDesc.dsc_length -= adjust; + node->dsqlDesc.dsc_length *= 3; + 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 @@ fb_assert(parameter && item); const char* name_alias = NULL; - const RecordKeyNode* dbKeyNode; + const ValueExprNode* exprNode; switch (item->nod_type) { @@ -887,23 +877,15 @@ exprNode->setParameterName(parameter); } 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: string = (dsql_str*) item->nod_arg[e_alias_alias]; 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]; - parameter->par_name = field->fld_name.c_str(); - context = (dsql_ctx*) alias->nod_arg[e_fld_context]; + exprNode->setParameterName(parameter); } - else if ((dbKeyNode = ExprNode::as<RecordKeyNode>(alias))) - dbKeyNode->setParameterName(parameter); parameter->par_alias = string->str_data; break; @@ -912,6 +894,7 @@ case nod_simple_case: name_alias = "CASE"; break; + case nod_coalesce: name_alias = "COALESCE"; break; @@ -919,20 +902,4 @@ if (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; - } } Modified: firebird/trunk/src/dsql/node.h =================================================================== --- firebird/trunk/src/dsql/node.h 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/node.h 2010-12-19 21:42:32 UTC (rev 52061) @@ -122,7 +122,6 @@ nod_flag, nod_join, nod_unique, - nod_field, nod_dom_value, nod_field_name, nod_alias, @@ -255,11 +254,6 @@ e_fpd_list = 0, // nod_for_update 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_indices, e_ary_count, Modified: firebird/trunk/src/dsql/pass1.cpp =================================================================== --- firebird/trunk/src/dsql/pass1.cpp 2010-12-19 18:57:17 UTC (rev 52060) +++ firebird/trunk/src/dsql/pass1.cpp 2010-12-19 21:42:32 UTC (rev 52061) @@ -391,14 +391,6 @@ 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: return visitChildren(node); } @@ -452,7 +444,6 @@ } case nod_relation: - case nod_field: return false; default: @@ -513,36 +504,6 @@ case nod_relation: 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: return visitChildren(node); } @@ -596,28 +557,6 @@ invalid |= visit(&node->nod_arg[e_agg_rse]); 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_unique: case nod_rse: @@ -674,15 +613,6 @@ 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: { AutoSetRestore<USHORT> autoCurrentLevel(¤tLevel, currentLevel + 1); @@ -756,7 +686,6 @@ case nod_aggregate: - case nod_field: case nod_relation: case nod_field_name: return false; @@ -1116,11 +1045,6 @@ return pass1_variable(dsqlScratch, input); 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: if (dsqlScratch->isPsql()) { @@ -2212,10 +2136,11 @@ if (elem1->nod_type == nod_assign && !is_insert) 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 = - reinterpret_cast<dsql_fld*>(elem1->nod_arg[e_fld_field])->fld_name; + const Firebird::MetaName& n1 = fieldNode1->dsqlField->fld_name; for (int j = i + 1; j < fields->nod_count; ++j) { @@ -2223,19 +2148,20 @@ if (elem2->nod_type == nod_assign && !is_insert) 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 = - reinterpret_cast<dsql_fld*>(elem2->nod_arg[e_fld_field])->fld_name; + const Firebird::MetaName& n2 = fieldNode2->dsqlField->fld_name; 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; - field_duplication(bad_rel ? bad_rel->rel_name.c_str() : 0, - n2.c_str(), - is_insert ? old_fields->nod_arg[j]: old_fields->nod_arg[j]->nod_arg[1], - dsqlScratch); + field_duplication((bad_rel ? bad_rel->rel_name.c_str() : 0), + n2.c_str(), + (is_insert ? old_fields->nod_arg[j] : old_fields->nod_arg[j]->nod_arg[1]), + dsqlScratch); } } } @@ -2585,19 +2511,6 @@ } 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: { const dsql_ctx* ctx1 = (dsql_ctx*) node1->nod_arg[e_derived_table_context]; @@ -2735,8 +2648,10 @@ thread_db* tdbb = JRD_get_thread_data(); PASS1_make_context(dsqlScratch, input->nod_arg[e_blb_relation]); - dsql_nod* field = pass1_field(dsqlScratch, input->nod_arg[e_blb_field], false, NULL); - if (field->nod_desc.dsc_dtype != dtype_blob) + FieldNode* field = ExprNode::as<FieldNode>( + 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) << Arg::Gds(isc_dsql_blob_err)); @@ -2758,8 +2673,8 @@ blob->blb_segment = parameter; parameter->par_desc.dsc_dtype = dtype_text; parameter->par_desc.dsc_ttype() = ttype_binary; - parameter->par_desc.dsc_length = ((dsql_fld*) field->nod_arg[e_fld_field])->fld_seg_length; - DEV_BLKCHK(field->nod_arg[e_fld_field], dsql_type_fld); + parameter->par_desc.dsc_length = field->dsqlField->fld_seg_length; + DEV_BLKCHK(field->dsqlField, dsql_type_fld); // 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 @@ -2773,7 +2688,7 @@ dsql_msg* temp_msg = (input->nod_type == nod_get_segment) ? blob->blb_open_in_msg : blob->blb_open_out_msg; 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_scale = 0; @@ -4243,28 +4158,24 @@ static dsql_nod* pass1_hidden_variable(DsqlCompilerScratch* dsqlScratch, dsql_nod*& expr) { // 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) - { - case ExprNode::TYPE_CURRENT_DATE: - case ExprNode::TYPE_CURRENT_TIME: - case ExprNode::TYPE_CURRENT_TIMESTAMP: - case ExprNode::TYPE_CURRENT_ROLE: - case ExprNode::TYPE_CURRENT_USER: - case ExprNode::TYPE_INTERNAL_INFO: - case ExprNode::TYPE_LITERAL: - case ExprNode::TYPE_NULL: - case ExprNode::TYPE_PARAMETER: - case ExprNode::TYPE_RECORD_KEY: - case ExprNode::TYPE_VARIABLE: - return NULL; - } - break; + switch (ExprNode::fromLegacy(expr)->type) + { + case ExprNode::TYPE_CURRENT_DATE: + case ExprNode::TYPE_CURRENT_TIME: + case ExprNode::TYPE_CURRENT_TIMESTAMP: + case ExprNode::TYPE_CURRENT_ROLE: + case ExprNode::TYPE_CURRENT_USER: + case ExprNode::TYPE_FIELD: + case ExprNode::TYPE_INTERNAL_INFO: + case ExprNode::TYPE_LITERAL: + case ExprNode::TYPE_NULL: + case ExprNode::TYPE_PARAMETER: + case ExprNode::TYPE_RECORD_KEY: + case ExprNode::TYPE_VARIABLE: + return NULL; + } } VariableNode* var = MAKE_variable(NULL, "", VAR_local, 0, 0, dsqlScratch->hiddenVarsNumber++); @@ -4349,13 +4260,14 @@ const dsql_ctx* tmp_ctx = NULL; const TEXT* tmp_name = NULL; + const FieldNode* fieldNode; 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_name = (temp2->nod_arg[e_fld_field] ? - ((dsql_fld*) temp2->nod_arg[e_fld_field])->fld_name.c_str() : NULL); + tmp_ctx = fieldNode->dsqlContext; + if (fieldNode->dsqlField) + tmp_name = fieldNode->dsqlField->fld_name.c_str(); } else if ((derivedField = ExprNode::as<DerivedFieldNode>(temp2))) { @@ -4543,6 +4455,7 @@ { const TEXT* name = NULL; dsql_nod* item = j.object(); + FieldNode* fieldNode; DerivedFieldNode* derivedField; switch (item->nod_type) @@ -4551,12 +4464,10 @@ name = reinterpret_cast<dsql_str*>(item->nod_arg[e_alias_alias])->str_data; break; - case nod_field: - name = reinterpret_cast<dsql_fld*>(item->nod_arg[e_fld_field])->fld_name.c_str(); - break; - 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(); break; } @@ -4865,6 +4776,7 @@ { dsql_nod* matchingNode = NULL; dsql_nod* node = *ptr; + FieldNode* fieldNode; DerivedFieldNode* derivedField; switch (node->nod_type) @@ -4878,16 +4790,13 @@ } break; - case nod_field: + default: + if ((fieldNode = ExprNode::as<FieldNode>(node))) { - const dsql_fld* field = (dsql_fld*) node->nod_arg[e_fld_field]; - if (field->fld_name == name->str_data) + if (fieldNode->dsqlField->fld_name == name->str_data) matchingNode = node; } - break; - - default: - if ((derivedField = ExprNode::as<DerivedFieldNode>(node))) + else if ((derivedField = ExprNode::as<DerivedFieldNode>(node))) { if (strcmp(derivedField->name.c_str(), name->str_data) == 0) matchingNode = node; @@ -4907,16 +4816,14 @@ buffer1[0] = 0; switch (returnNode->nod_type) { - case nod_field: - strcat(buffer1, "a field"); - break; - case nod_alias: strcat(buffer1, "an alias"); break; 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"); else strcat(buffer1, "an item"); @@ -4928,16 +4835,14 @@ switch (matchingNode->nod_type) { - case nod_field: - strcat(buffer2, "a field"); - break; - case nod_alias: strcat(buffer2, "an alias"); break; 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"); else strcat(buffer2, "an item"); @@ -4980,23 +4885,6 @@ 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: { const dsql_str* alias_alias = (dsql_str*) select_item->nod_arg[e_alias_alias]; @@ -5017,6 +4905,7 @@ { SubQueryNode* subQueryNode; DsqlMapNode* mapNode; + FieldNode* fieldNode; DerivedFieldNode* derivedField; if ((subQueryNode = ExprNode::as<SubQueryNode>(select_item))) @@ -5045,6 +4934,19 @@ 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))) { // Create a derived field that points to a derived field. @@ -7086,16 +6988,17 @@ 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 alias_node = MAKE_node(nod_alias, e_alias_count); // Copy fieldname to a new string. dsql_str* str_alias = FB_NEW_RPT(*tdbb->getDefaultPool(), - sub_field->fld_name.length()) dsql_str; - strcpy(str_alias->str_data, sub_field->fld_name.c_str()); - str_alias->str_length = sub_field->fld_name.length(); + fieldNode->dsqlField->fld_name.length()) dsql_str; + strcpy(str_alias->str_data, fieldNode->dsqlField->fld_name.c_str()); + str_alias->str_length = fieldNode->dsqlField->fld_name.length(); alias_node->nod_arg[e_alias_alias] = (dsql_nod*) str_alias; } } @@ -7965,24 +7868,27 @@ PASS1_field_unknown(qualifier.c_str(), name->str_data, flawedNode); } + FieldNode* fieldNode; 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; 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); ctx = reinterpret_cast<ImplicitJoin*>(node->nod_arg[e_alias_imp_join])->visibleInContext; - break; - default: + } + else + { fb_assert(false); } @@ -8107,10 +8013,10 @@ if (!par_node) return; - // Could it be something else ??? - fb_assert(fld_node->nod_type == nod_field); + const FieldNode* fieldNode = ExprNode::as<FieldNode>(fld_node); + 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; switch (par_node->nod_type) @@ -8141,9 +8047,7 @@ { ParameterNode* paramNode = exprNode->as<ParameterNode>(); dsql_par* parameter = paramNode->dsqlParameter; - const dsql_fld* field = (dsql_fld*) fld_node->nod_arg[e_fld_field]; - DEV_BLKCHK(field, dsql_type_fld); - parameter->par_name = field->fld_name.c_str(); + parameter->par_name = fieldNode->dsqlField->fld_name.c_str(); parameter->par_rel_name = relation->rel_name.c_str(); break; } @@ -8790,20 +8694,6 @@ 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: trace_line("%sfield name: \"", buffer); string = (dsql_str*) node->nod_arg[e_fln_context]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |