Skip to content

DB BaseBuilder Join() - RawSql as table #9070

Open
@sclubricants

Description

@sclubricants

PHP Version

8.2

CodeIgniter4 Version

4.5.3

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

No response

What happened?

CRITICAL - 2024-07-24 14:10:15 --> TypeError: CodeIgniter\Database\BaseBuilder::join(): Argument #1 ($table) must be of type string, CodeIgniter\Database\RawSql given, called in C:\xampp\portal\vendor\codeigniter4\framework\system\Model.php on line 930
[Method: GET, Route: public/fuel/pricing/getprice]
in SYSTEMPATH\Database\BaseBuilder.php on line 620.
1 SYSTEMPATH\Model.php(930): CodeIgniter\Database\BaseBuilder->join(Object(CodeIgniter\Database\RawSql), 't5.product_id = fpp.id', 'inner')

Steps to Reproduce

Used to be able to use RawSql for table on join()

        $builder = $this
            ->select("{$this->table}.description_id AS id, fpd.description,
                    fpp.product,
                    DATE({$this->table}.effective) AS effective,
                    {$priceField}")
            ->join(
                "{$this->descTable} AS fpd",
                "fpd.id = {$this->table}.description_id",
                'inner'
            )
            ->join(
                "{$this->prodTable} AS fpp",
                "fpp.id = {$this->table}.product_id",
                'inner'
            );

        $sql = "(SELECT
		fpp.id AS product_id,
		IF(ph.TAXCLASS IS NULL,0,ph.TAXCLASS) AS taxclass,
		IF(pw.SALESTAXCLASS IS NULL,0,pw.SALESTAXCLASS) AS salestaxclass
		FROM
		misc.fuel_prices_product AS fpp
		LEFT JOIN pds.pds_prodhead AS ph ON ph.PRODUCTCODE = fpp.product
		LEFT JOIN pds.pds_prodware AS pw ON pw.PRODUCTCODE = fpp.product AND pw.PACKCODE = '' AND pw.WHALPHA = 3
		GROUP BY fpp.id) t5";

        $builder->join(
            new RawSql($sql),
            "t5.product_id = `fpp`.id",
            'inner'
        );

        // $params['id'] = 14;
        $builder->where("{$this->table}.description_id", $params['id']);

        $builder->where("DATE({$this->table}.effective) BETWEEN DATE_SUB('{$params['fromdate']}',INTERVAL 15 DAY) AND '{$params['todate']}'");

        $builder->where('fpp.product', $params['product']);

        $builder->groupBY("DATE({$this->table}.effective)");

        $builder->orderBy("{$this->table}.effective", 'ASC');

        $data = $builder->get()->getResultObject();

Expected Output

Get errors now.

Fix by adding adding RawSq type:

    public function join(string|RawSql $table, $cond, string $type = '', ?bool $escape = null)
    {

Adding is_string($table) twice in BaseBuilder::trackAliases()

    protected function trackAliases($table)
    {
        if (is_array($table)) {
            foreach ($table as $t) {
                $this->trackAliases($t);
            }

            return;
        }

        // Does the string contain a comma?  If so, we need to separate
        // the string into discreet statements
        if (is_string($table) && str_contains($table, ',')) {
            return $this->trackAliases(explode(',', $table));
        }

        // if a table alias is used we can recognize it by a space
        if (is_string($table) && str_contains($table, ' ')) {

Anything else?

I'd send in a PR but I'm slammed busy at the moment and I don't have my development environment ready.

Metadata

Metadata

Assignees

No one assigned

    Labels

    databaseIssues or pull requests that affect the database layerenhancementPRs that improve existing functionalities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions