PASS1_node_match @brief Compare two nodes for equality of value. [2002-08-04]--- Arno Brinkman If ignoreMapCast is true and the node1 is type nod_cast or nod_map then PASS1_node_match is calling itselfs again with the node1 CASTs source or map->node. This is for allow CAST to other datatypes without complaining that it's an unknown column reference. (Aggregate function
| 804 | |
| 805 | **/ |
| 806 | bool PASS1_node_match(DsqlCompilerScratch* dsqlScratch, const ExprNode* node1, const ExprNode* node2, |
| 807 | bool ignoreMapCast) |
| 808 | { |
| 809 | thread_db* tdbb = JRD_get_thread_data(); |
| 810 | |
| 811 | DEV_BLKCHK(node1, dsql_type_nod); |
| 812 | DEV_BLKCHK(node2, dsql_type_nod); |
| 813 | |
| 814 | JRD_reschedule(tdbb); |
| 815 | |
| 816 | if (!node1 && !node2) |
| 817 | return true; |
| 818 | |
| 819 | if (!node1 || !node2) |
| 820 | return false; |
| 821 | |
| 822 | const CastNode* castNode1 = nodeAs<CastNode>(node1); |
| 823 | |
| 824 | if (ignoreMapCast && castNode1) |
| 825 | { |
| 826 | const CastNode* castNode2 = nodeAs<CastNode>(node2); |
| 827 | |
| 828 | // If node2 is also cast and same type continue with both sources. |
| 829 | if (castNode2 && |
| 830 | castNode1->castDesc.dsc_dtype == castNode2->castDesc.dsc_dtype && |
| 831 | castNode1->castDesc.dsc_scale == castNode2->castDesc.dsc_scale && |
| 832 | castNode1->castDesc.dsc_length == castNode2->castDesc.dsc_length && |
| 833 | castNode1->castDesc.dsc_sub_type == castNode2->castDesc.dsc_sub_type) |
| 834 | { |
| 835 | return PASS1_node_match(dsqlScratch, castNode1->source, castNode2->source, ignoreMapCast); |
| 836 | } |
| 837 | |
| 838 | return PASS1_node_match(dsqlScratch, castNode1->source, node2, ignoreMapCast); |
| 839 | } |
| 840 | |
| 841 | const DsqlMapNode* mapNode1 = nodeAs<DsqlMapNode>(node1); |
| 842 | |
| 843 | if (ignoreMapCast && mapNode1) |
| 844 | { |
| 845 | const DsqlMapNode* mapNode2 = nodeAs<DsqlMapNode>(node2); |
| 846 | |
| 847 | if (mapNode2) |
| 848 | { |
| 849 | if (mapNode1->context != mapNode2->context) |
| 850 | return false; |
| 851 | |
| 852 | return PASS1_node_match(dsqlScratch, mapNode1->map->map_node, mapNode2->map->map_node, ignoreMapCast); |
| 853 | } |
| 854 | |
| 855 | return PASS1_node_match(dsqlScratch, mapNode1->map->map_node, node2, ignoreMapCast); |
| 856 | } |
| 857 | |
| 858 | const DsqlAliasNode* aliasNode1 = nodeAs<DsqlAliasNode>(node1); |
| 859 | const DsqlAliasNode* aliasNode2 = nodeAs<DsqlAliasNode>(node2); |
| 860 | |
| 861 | // We don't care about the alias itself but only about its field. |
| 862 | if (aliasNode1 || aliasNode2) |
| 863 | { |
no test coverage detected