codeigniter4 / codeigniter4/CodeIgniter4

DB BaseBuilder Join() - RawSql as table

Đang mở
#9,070 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
database enhancement
Ngôn ngữ chính
PHP
Star
6k
Fork
2k
Merge trung bình
1 ngày 11 giờ
Pull request đã merge (30 ngày)
73

Mô tả

### 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()

```php
$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:

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

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

```php
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.**

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.