Skip to content

Commit e2c86bd

Browse files
committed
don't use temp space
1 parent 46c836b commit e2c86bd

File tree

3 files changed

+45
-18
lines changed

3 files changed

+45
-18
lines changed

doc/sql.extensions/README.generate_series.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@ The interval and the step between series values ​​are defined by the user.
1313
## Arguments
1414

1515
* `start` - The first value in the interval. `start` is specified as a variable, a literal, or a scalar expression of type
16-
`smallint`, `integer` or `bigint`.
16+
`smallint`, `integer`, `bigint` or `numeric(18, x)`.
1717

1818
* `finish` - The last value in the interval. `finish` is specified as a variable, a literal, or a scalar expression of
19-
type `smallint`, `integer` or `bigint`. The series stops once the last generated step value exceeds the `finish` value.
19+
type `smallint`, `integer`, `bigint` or `numeric(18, x)`. The series stops once the last generated step value exceeds
20+
the `finish` value.
2021

2122
* `step` - Indicates the number of values to increment or decrement between steps in the series. `step` is an expression
22-
of type `smallint`, `integer` or `bigint`. `step` can be either negative or positive, but can't be zero (0). This
23+
of type `smallint`, `integer`, `bigint` or `numeric(18, x)`. `step` can be either negative or positive, but can't be zero (0). This
2324
argument is optional. The default value for `step` is 1.
2425

2526
## Returning type
2627

27-
The function `GENERATE_SERIES` returns a set with a `BIGINT` column.
28+
The function `GENERATE_SERIES` returns a set with `BIGINT` or `NUMERIC(18, x)` column, where the scale is
29+
determined by the maximum of the scales of the function arguments.
2830

2931
## Rules
3032

@@ -41,7 +43,10 @@ SELECT n
4143
FROM GENERATE_SERIES(1, 3) AS S(n);
4244
4345
SELECT n
44-
FROM GENERATE_SERIES(3, 1, 1) AS S(n);
46+
FROM GENERATE_SERIES(3, 1, -1) AS S(n);
47+
48+
SELECT n
49+
FROM GENERATE_SERIES(0, 9.9, 0.1) AS S(n);
4550
4651
SELECT
4752
DATEADD(n MINUTE TO timestamp '2025-01-01 12:00') AS START_TIME,

src/jrd/recsrc/RecordSource.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,7 @@ namespace Jrd
16321632
SINT64 m_step;
16331633
SINT64 m_result;
16341634
SCHAR m_scale;
1635+
bool m_recordExists;
16351636
};
16361637

16371638
public:
@@ -1643,6 +1644,7 @@ namespace Jrd
16431644
void internalOpen(thread_db* tdbb) const final;
16441645
void internalGetPlan(thread_db* tdbb, PlanEntry& planEntry, unsigned level,
16451646
bool recurse) const final;
1647+
bool internalGetRecord(thread_db* tdbb) const final;
16461648

16471649
bool nextBuffer(thread_db* tdbb) const final;
16481650

src/jrd/recsrc/TableValueFunctionScan.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,7 @@ void GenSeriesFunctionScan::close(thread_db* tdbb) const
367367
const auto impure = request->getImpure<Impure>(m_impure);
368368

369369
if (impure->irsb_flags & irsb_open)
370-
{
371370
impure->irsb_flags &= ~irsb_open;
372-
373-
if (impure->m_recordBuffer)
374-
{
375-
delete impure->m_recordBuffer;
376-
impure->m_recordBuffer = nullptr;
377-
}
378-
}
379371
}
380372

381373

@@ -431,16 +423,15 @@ void GenSeriesFunctionScan::internalOpen(thread_db* tdbb) const
431423
if (step == 0)
432424
status_exception::raise(Arg::Gds(isc_genseq_stepmustbe_nonzero) << Arg::Str(m_name));
433425

434-
435426
const auto impure = request->getImpure<Impure>(m_impure);
436427
impure->irsb_flags |= irsb_open;
437-
impure->m_recordBuffer = FB_NEW_POOL(pool) RecordBuffer(pool, m_format);
428+
impure->m_recordBuffer = nullptr;
438429
impure->m_start = start;
439430
impure->m_finish = finish;
440431
impure->m_step = step;
441432
impure->m_result = start;
442433
impure->m_scale = scale;
443-
434+
impure->m_recordExists = true;
444435

445436
Record* const record = VIO_record(tdbb, rpb, m_format, &pool);
446437

@@ -450,7 +441,6 @@ void GenSeriesFunctionScan::internalOpen(thread_db* tdbb) const
450441
fromDesc.makeInt64(scale, &impure->m_result);
451442

452443
assignParameter(tdbb, &fromDesc, toDesc, 0, record);
453-
impure->m_recordBuffer->store(record);
454444
}
455445

456446
void GenSeriesFunctionScan::internalGetPlan(thread_db* tdbb, PlanEntry& planEntry, unsigned /*level*/,
@@ -467,6 +457,36 @@ void GenSeriesFunctionScan::internalGetPlan(thread_db* tdbb, PlanEntry& planEntr
467457
planEntry.alias = m_alias;
468458
}
469459

460+
bool GenSeriesFunctionScan::internalGetRecord(thread_db* tdbb) const
461+
{
462+
JRD_reschedule(tdbb);
463+
464+
const auto request = tdbb->getRequest();
465+
const auto impure = request->getImpure<Impure>(m_impure);
466+
const auto rpb = &request->req_rpb[m_stream];
467+
468+
if (!(impure->irsb_flags & irsb_open))
469+
{
470+
rpb->rpb_number.setValid(false);
471+
return false;
472+
}
473+
474+
rpb->rpb_number.increment();
475+
476+
do
477+
{
478+
if (impure->m_recordExists)
479+
{
480+
impure->m_recordExists = false;
481+
rpb->rpb_number.setValid(true);
482+
return true;
483+
}
484+
} while (nextBuffer(tdbb));
485+
486+
rpb->rpb_number.setValid(false);
487+
return false;
488+
}
489+
470490
bool GenSeriesFunctionScan::nextBuffer(thread_db* tdbb) const
471491
{
472492
const auto request = tdbb->getRequest();
@@ -481,7 +501,7 @@ bool GenSeriesFunctionScan::nextBuffer(thread_db* tdbb) const
481501
dsc fromDesc;
482502
fromDesc.makeInt64(impure->m_scale, &i);
483503
assignParameter(tdbb, &fromDesc, toDesc, 0, record);
484-
impure->m_recordBuffer->store(record);
504+
impure->m_recordExists = true;
485505
};
486506

487507
impure->m_result += impure->m_step;

0 commit comments

Comments
 (0)