@@ -405,32 +405,60 @@ void GenSeriesFunctionScan::internalOpen(thread_db* tdbb) const
405405 return ;
406406 }
407407
408- // common scale
409- const auto scale = MIN ( MIN (startDesc-> dsc_scale , finishDesc-> dsc_scale ), stepDesc-> dsc_scale ) ;
408+ const auto impure = request-> getImpure <Impure>(m_impure);
409+ impure-> m_recordBuffer = nullptr ;
410410
411- const auto start = MOV_get_int64 (tdbb, startDesc, scale);
412- const auto finish = MOV_get_int64 (tdbb, finishDesc, scale);
413- const auto step = MOV_get_int64 (tdbb, stepDesc, scale);
411+ // common scale
412+ impure->m_scale = MIN (MIN (startDesc->dsc_scale , finishDesc->dsc_scale ), stepDesc->dsc_scale );
413+ // common type
414+ impure->m_dtype = MAX (MAX (startDesc->dsc_dtype , finishDesc->dsc_dtype ), stepDesc->dsc_dtype );
414415
415- // validate parameter value
416- if (((step > 0 ) && (start > finish)) ||
417- ((step < 0 ) && (start < finish)))
416+ if (impure->m_dtype != dtype_int128)
418417 {
419- rpb->rpb_number .setValid (false );
420- return ;
418+ const auto start = MOV_get_int64 (tdbb, startDesc, impure->m_scale );
419+ const auto finish = MOV_get_int64 (tdbb, finishDesc, impure->m_scale );
420+ const auto step = MOV_get_int64 (tdbb, stepDesc, impure->m_scale );
421+
422+ if (step == 0 )
423+ status_exception::raise (Arg::Gds (isc_genseq_stepmustbe_nonzero) << Arg::Str (m_name));
424+
425+ // validate parameter value
426+ if (((step > 0 ) && (start > finish)) ||
427+ ((step < 0 ) && (start < finish)))
428+ {
429+ rpb->rpb_number .setValid (false );
430+ return ;
431+ }
432+
433+ impure->m_start = start;
434+ impure->m_finish = finish;
435+ impure->m_step = step;
421436 }
437+ else {
438+ const auto start = MOV_get_int128 (tdbb, startDesc, impure->m_scale );
439+ const auto finish = MOV_get_int128 (tdbb, finishDesc, impure->m_scale );
440+ const auto step = MOV_get_int128 (tdbb, stepDesc, impure->m_scale );
422441
423- if (step == 0 )
424- status_exception::raise (Arg::Gds (isc_genseq_stepmustbe_nonzero) << Arg::Str (m_name));
442+ if (step. sign () == 0 )
443+ status_exception::raise (Arg::Gds (isc_genseq_stepmustbe_nonzero) << Arg::Str (m_name));
425444
426- const auto impure = request->getImpure <Impure>(m_impure);
445+ // validate parameter value
446+ if (((step.sign () > 0 ) && (start.compare (finish) > 0 )) ||
447+ ((step.sign () < 0 ) && (start.compare (finish) < 0 )))
448+ {
449+ rpb->rpb_number .setValid (false );
450+ return ;
451+ }
452+
453+ impure->m_start = start;
454+ impure->m_finish = finish;
455+ impure->m_step = step;
456+ }
457+
458+
427459 impure->irsb_flags |= irsb_open;
428- impure->m_recordBuffer = nullptr ;
429- impure->m_start = start;
430- impure->m_finish = finish;
431- impure->m_step = step;
432- impure->m_result = start;
433- impure->m_scale = scale;
460+ impure->m_result = impure->m_start ;
461+
434462
435463 VIO_record (tdbb, rpb, m_format, &pool);
436464}
@@ -465,7 +493,8 @@ bool GenSeriesFunctionScan::internalGetRecord(thread_db* tdbb) const
465493
466494 rpb->rpb_number .increment ();
467495
468- if (nextBuffer (tdbb)) {
496+ if (nextBuffer (tdbb))
497+ {
469498 rpb->rpb_number .setValid (true );
470499 return true ;
471500 }
@@ -479,20 +508,50 @@ bool GenSeriesFunctionScan::nextBuffer(thread_db* tdbb) const
479508 const auto request = tdbb->getRequest ();
480509 const auto impure = request->getImpure <Impure>(m_impure);
481510
482- if (((impure->m_step > 0 ) && (impure->m_result <= impure->m_finish )) ||
483- ((impure->m_step < 0 ) && (impure->m_result >= impure->m_finish )))
511+ if (impure->m_dtype != dtype_int128)
484512 {
485- Record* const record = request->req_rpb [m_stream].rpb_record ;
513+ auto result = std::get<SINT64>(impure->m_result );
514+ const auto finish = std::get<SINT64>(impure->m_finish );
515+ const auto step = std::get<SINT64>(impure->m_step );
516+
517+ if (((step > 0 ) && (result <= finish)) ||
518+ ((step < 0 ) && (result >= finish)))
519+ {
520+ Record* const record = request->req_rpb [m_stream].rpb_record ;
486521
487- auto toDesc = m_format->fmt_desc .begin ();
522+ auto toDesc = m_format->fmt_desc .begin ();
488523
489- dsc fromDesc;
490- fromDesc.makeInt64 (impure->m_scale , &impure-> m_result );
491- assignParameter (tdbb, &fromDesc, toDesc, 0 , record);
524+ dsc fromDesc;
525+ fromDesc.makeInt64 (impure->m_scale , &result );
526+ assignParameter (tdbb, &fromDesc, toDesc, 0 , record);
492527
493- impure->m_result += impure->m_step ;
528+ result += step;
529+ impure->m_result = result;
494530
495- return true ;
531+ return true ;
532+ }
533+ }
534+ else {
535+ auto result = std::get<Firebird::Int128>(impure->m_result );
536+ const auto finish = std::get<Firebird::Int128>(impure->m_finish );
537+ const auto step = std::get<Firebird::Int128>(impure->m_step );
538+
539+ if (((step.sign () > 0 ) && (result.compare (finish) <= 0 )) ||
540+ ((step.sign () < 0 ) && (result.compare (finish) >= 0 )))
541+ {
542+ Record* const record = request->req_rpb [m_stream].rpb_record ;
543+
544+ auto toDesc = m_format->fmt_desc .begin ();
545+
546+ dsc fromDesc;
547+ fromDesc.makeInt128 (impure->m_scale , &result);
548+ assignParameter (tdbb, &fromDesc, toDesc, 0 , record);
549+
550+ result = result.add (step);
551+ impure->m_result = result;
552+
553+ return true ;
554+ }
496555 }
497556
498557 return false ;
0 commit comments