Repository: typeorm/typeorm
File: src/query-builder/SelectQueryBuilder.ts (TypeScript)

Code before:
        if (this.expressionMap.joinAttributes.length > 0 && hasLimit) {
            return undefined
        }

        const hasTake =
            this.expressionMap.take !== undefined &&
            this.expressionMap.take !== null

        // limit overrides take when no join is defined
        const maxResults = hasLimit
            ? this.expressionMap.limit
            : hasTake
            ? this.expressionMap.take
            : undefined

        if (
            maxResults !== undefined &&
            entitiesAndRaw.entities.length === maxResults
        ) {
            // stop here when the result set contains the max number of rows; we need to execute a full count
            return undefined
        }

        if (entitiesAndRaw.entities.length === 0) {
            return undefined;
        }

        const hasSkip =
            this.expressionMap.skip !== undefined &&
            this.expressionMap.skip !== null &&
            this.expressionMap.skip > 0
        const hasOffset =
            this.expressionMap.offset !== undefined &&
            this.expressionMap.offset !== null &&
            this.expressionMap.offset > 0

        // offset overrides skip when no join is defined
        const previousResults: number = hasOffset
            ? this.expressionMap.offset!
            : hasSkip
            ? this.expressionMap.skip!
            : 0

        return entitiesAndRaw.entities.length + previousResults
    }

    /**
     * Executes built SQL query and returns raw data stream.
     */
    async stream(): Promise<ReadStream> {
        this.expressionMap.queryEntity = false

Review comment (refactor):
In cases where skip/offset were not used, the lazy count can still be trusted when the result set is empty. So let's move this down and condition it on that:


```ts
        const hasSkip =
this.expressionMap.skip !== undefined &&
this.expressionMap.skip !== null &&
this.expressionMap.skip > 0
        const hasOffset =
this.expressionMap.offset !== undefined &&
this.expressionMap.offset !== null &&
this.expressionMap.offset > 0

        if (entitiesAndRaw.entities.length === 0 && (hasSkip || hasOffset)) {
            // when skip or offset were used and no results found, we need to execute a full count
            // (the given offset may have exceeded the actual number of rows)
            return undefined
        }
```

Code after:
        if (this.expressionMap.joinAttributes.length > 0 && hasLimit) {
            return undefined
        }

        const hasTake =
            this.expressionMap.take !== undefined &&
            this.expressionMap.take !== null

        // limit overrides take when no join is defined
        const maxResults = hasLimit
            ? this.expressionMap.limit
            : hasTake
            ? this.expressionMap.take
            : undefined

        if (
            maxResults !== undefined &&
            entitiesAndRaw.entities.length === maxResults
        ) {
            // stop here when the result set contains the max number of rows; we need to execute a full count
            return undefined
        }

        const hasSkip =
            this.expressionMap.skip !== undefined &&
            this.expressionMap.skip !== null &&
            this.expressionMap.skip > 0
        const hasOffset =
            this.expressionMap.offset !== undefined &&
            this.expressionMap.offset !== null &&
            this.expressionMap.offset > 0

        if (entitiesAndRaw.entities.length === 0 && (hasSkip || hasOffset)) {
            // when skip or offset were used and no results found, we need to execute a full count
            // (the given offset may have exceeded the actual number of rows)
            return undefined
        }

        // offset overrides skip when no join is defined
        const previousResults: number = hasOffset
            ? this.expressionMap.offset!
            : hasSkip
            ? this.expressionMap.skip!
            : 0

        return entitiesAndRaw.entities.length + previousResults
    }

    /**
     * Executes built SQL query and returns raw data stream.
     */