@@ -1467,6 +1467,173 @@ AggNode* MaxMinAggNode::dsqlCopy(DsqlCompilerScratch* dsqlScratch) /*const*/
14671467 type, doDsqlPass (dsqlScratch, arg));
14681468}
14691469
1470+ // --------------------
1471+
1472+ static AggNode::RegisterFactory1<BinAggNode, BinAggNode::BinType> binAndAggInfo (
1473+ " BIN_AND_AGG" , BinAggNode::TYPE_BIN_AND);
1474+ static AggNode::RegisterFactory1<BinAggNode, BinAggNode::BinType> binOrAggInfo (
1475+ " BIN_OR_AGG" , BinAggNode::TYPE_BIN_OR);
1476+ static AggNode::RegisterFactory1<BinAggNode, BinAggNode::BinType> binXorAggInfo (
1477+ " BIN_XOR_AGG" , BinAggNode::TYPE_BIN_XOR);
1478+ static AggNode::RegisterFactory1<BinAggNode, BinAggNode::BinType> binXorDistinctAggInfo (
1479+ " BIN_XOR_DISTINCT_AGG" , BinAggNode::TYPE_BIN_XOR_DISTINCT);
1480+
1481+ BinAggNode::BinAggNode (MemoryPool& pool, BinType aType, ValueExprNode* aArg)
1482+ : AggNode(pool,
1483+ (aType == BinAggNode::TYPE_BIN_AND ? binAndAggInfo :
1484+ aType == BinAggNode::TYPE_BIN_OR ? binOrAggInfo :
1485+ aType == BinAggNode::TYPE_BIN_XOR ? binXorAggInfo : binXorDistinctAggInfo),
1486+ (aType == BinAggNode::TYPE_BIN_XOR_DISTINCT), false, aArg),
1487+ type(aType)
1488+ {
1489+ }
1490+
1491+ void BinAggNode::parseArgs (thread_db* tdbb, CompilerScratch* csb, unsigned /* count*/ )
1492+ {
1493+ arg = PAR_parse_value (tdbb, csb);
1494+ }
1495+
1496+ void BinAggNode::make (DsqlCompilerScratch* dsqlScratch, dsc* desc)
1497+ {
1498+ DsqlDescMaker::fromNode (dsqlScratch, desc, arg, true );
1499+
1500+ if (desc->isNull ())
1501+ return ;
1502+
1503+ if (!DTYPE_IS_EXACT (desc->dsc_dtype ) || (desc->dsc_scale != 0 ))
1504+ {
1505+ switch (type)
1506+ {
1507+ case TYPE_BIN_AND:
1508+ ERRD_post (Arg::Gds (isc_expression_eval_err) <<
1509+ Arg::Gds (isc_dsql_agg2_wrongarg) << Arg::Str (" BIN_AND_AGG" ));
1510+ break ;
1511+
1512+ case TYPE_BIN_OR:
1513+ ERRD_post (Arg::Gds (isc_expression_eval_err) <<
1514+ Arg::Gds (isc_dsql_agg2_wrongarg) << Arg::Str (" BIN_OR_AGG" ));
1515+ break ;
1516+
1517+ case TYPE_BIN_XOR:
1518+ case TYPE_BIN_XOR_DISTINCT:
1519+ ERRD_post (Arg::Gds (isc_expression_eval_err) <<
1520+ Arg::Gds (isc_dsql_agg2_wrongarg) << Arg::Str (" BIN_XOR_AGG" ));
1521+ break ;
1522+
1523+ default :
1524+ fb_assert (false );
1525+ break ;
1526+ }
1527+ }
1528+ }
1529+
1530+ void BinAggNode::getDesc (thread_db* tdbb, CompilerScratch* csb, dsc* desc)
1531+ {
1532+ arg->getDesc (tdbb, csb, desc);
1533+
1534+ if (desc->is128 ())
1535+ {
1536+ nodFlags |= FLAG_INT128;
1537+ desc->makeInt128 (0 );
1538+ }
1539+ else
1540+ desc->makeInt64 (0 );
1541+ }
1542+
1543+ ValueExprNode* BinAggNode::copy (thread_db* tdbb, NodeCopier& copier) const
1544+ {
1545+ BinAggNode* node = FB_NEW_POOL (*tdbb->getDefaultPool ()) BinAggNode (*tdbb->getDefaultPool (), type);
1546+ node->arg = copier.copy (tdbb, arg);
1547+ return node;
1548+ }
1549+
1550+ string BinAggNode::internalPrint (NodePrinter& printer) const
1551+ {
1552+ AggNode::internalPrint (printer);
1553+
1554+ NODE_PRINT (printer, type);
1555+
1556+ return " BinAggNode" ;
1557+ }
1558+
1559+ void BinAggNode::aggInit (thread_db* tdbb, Request* request) const
1560+ {
1561+ AggNode::aggInit (tdbb, request);
1562+
1563+ SINT64 initValue = 0 ;
1564+ if (type == TYPE_BIN_AND)
1565+ initValue = -1 ;
1566+
1567+ impure_value_ex* impure = request->getImpure <impure_value_ex>(impureOffset);
1568+ if (nodFlags & FLAG_INT128)
1569+ {
1570+ Firebird::Int128 i128 ;
1571+ impure->make_decimal_fixed (i128 , 0 );
1572+ impure->vlu_misc .vlu_int128 = initValue;
1573+ }
1574+ else
1575+ impure->make_int64 (initValue);
1576+ }
1577+
1578+ void BinAggNode::aggPass (thread_db* tdbb, Request* request, dsc* desc) const
1579+ {
1580+ impure_value_ex* impure = request->getImpure <impure_value_ex>(impureOffset);
1581+ ++impure->vlux_count ;
1582+ if (nodFlags & FLAG_INT128)
1583+ {
1584+ const auto value = MOV_get_int128 (tdbb, desc, 0 );
1585+ switch (type)
1586+ {
1587+ case TYPE_BIN_AND:
1588+ impure->vlu_misc .vlu_int128 &= value;
1589+ break ;
1590+
1591+ case TYPE_BIN_OR:
1592+ impure->vlu_misc .vlu_int128 |= value;
1593+ break ;
1594+
1595+ case TYPE_BIN_XOR:
1596+ case TYPE_BIN_XOR_DISTINCT:
1597+ impure->vlu_misc .vlu_int128 ^= value;
1598+ break ;
1599+ }
1600+ }
1601+ else
1602+ {
1603+ const auto value = MOV_get_int64 (tdbb, desc, 0 );
1604+ switch (type)
1605+ {
1606+ case TYPE_BIN_AND:
1607+ impure->vlu_misc .vlu_int64 &= value;
1608+ break ;
1609+
1610+ case TYPE_BIN_OR:
1611+ impure->vlu_misc .vlu_int64 |= value;
1612+ break ;
1613+
1614+ case TYPE_BIN_XOR:
1615+ case TYPE_BIN_XOR_DISTINCT:
1616+ impure->vlu_misc .vlu_int64 ^= value;
1617+ break ;
1618+ }
1619+ }
1620+ }
1621+
1622+ dsc* BinAggNode::aggExecute (thread_db* tdbb, Request* request) const
1623+ {
1624+ impure_value_ex* impure = request->getImpure <impure_value_ex>(impureOffset);
1625+
1626+ if (!impure->vlux_count )
1627+ return nullptr ;
1628+
1629+ return &impure->vlu_desc ;
1630+ }
1631+
1632+ AggNode* BinAggNode::dsqlCopy (DsqlCompilerScratch* dsqlScratch) /* const*/
1633+ {
1634+ return FB_NEW_POOL (dsqlScratch->getPool ()) BinAggNode (dsqlScratch->getPool (),
1635+ type, doDsqlPass (dsqlScratch, arg));
1636+ }
14701637
14711638// --------------------
14721639
0 commit comments