<commit_before><?php


trait pudlQuery {


	public function escape($value) {
		switch (true) {
			case is_int($value):
			case is_float($value):
			case is_null($value):
			case is_bool($value):
				return $value;
		}

		return str_replace(
			['\\',		"\0",	"\x08",	"\x26",	"'",	'"',	"\n",	"\r",	"\t"],
			['\\\\',	'\0',	'\b',	'\Z',	"\'",	'\"',	'\n',	'\r',	'\t'],
			(string)$value
		);
	}



	public function likeEscape($value) {
		return addcslashes($this->escape($value), '%_');
	}



	public function setEscape($value) {
		return str_replace(',', '', $value);
	}



	protected function _cache() {
		return '';
	}



	public function _value($value, $quote=true, $isnull=false) {
		static $depth = 0;
		$query = false;

		if ($depth++ > 31) {
			throw new pudlException('Recursion limit reached');
			return $query;
		}

		switch (true) {

			//THIS IS FOR AND/OR RECUSION, HANDLED ELSEWHERE
			//IN THIS CASE, DO NOTHING!
			case is_array($value): break;


			case is_int($value):
			case is_float($value):
				if (is_nan($value)  ||  is_infinite($value)) {
					$query = $isnull ? ' IS NULL' : 'NULL';
				} else {
					$query = $value;
				}
			break;


			case is_string($value):
				$query = $quote ? "'".$this->escape($value)."'" : $value;
			break;


			case is_bool($value):
				$query = $value ? 'TRUE' : 'FALSE';
			break;


			case is_null($value):
				$query = $isnull ? ' IS NULL' : 'NULL';
			break;


			case $value instanceof pudlValue:
				$query = $value->pudlValue($this, $quote);
			break;


			case is_callable([$value, '__toString']):
				$query = $quote
					? "'" . $this->escape((string)$value) . "'"
					: (string)$value;
			break;


			default:
				return $this->_invalidType($value);
		}


		$depth--;
		return $query;
	}



	private function _regexp($value) {
		$query = '';
		if (!pudl_array($value)) $value = [$value];
		foreach ($value as $item) {
			$query .= is_string($item) ?
				$this->escape(preg_quote($item)) :
				$this->_value($item, false);
		}
		return "'".$query."'";
	}



	protected function _column($column) {
		if ($column instanceof pudlId) {
			$column = key( $column->pudlId() );
		}

		if (!pudl_array($column)) {
			switch ($column) {
				case '':
				case '*':
				case null:
				case false:
					return '*';
			}
			return $this->_value($column, false);
		}

		$query = '';
		foreach ($column as $key => $value) {
			if (strlen($query)) $query .= ', ';
			if (is_string($key)) {
				if (is_string($value)) {
					$query .= $this->identifiers($value);
				} else {
					$query .= $this->_value($value, true);
				}
				$query .= ' AS ' . $this->identifier($key);
			} else {
				$query .= $this->_value($value, is_string($key));
			}
		}

		return $query;
	}



	public function identifier($identifier) {
		if ($identifier instanceof pudlHelper) {
			return $this->_value($identifier);
		}

		return $this->identifier . str_replace(
			$this->identifier,
			$this->identifier.$this->identifier,
			$identifier
		) . $this->identifier;
	}



	public function identifiers($identifiers, $prefix=false) {
		if ($identifiers === false) return '';

		//PUDL HELPERS HAVE SPECIAL HANDLERS
		if ($identifiers instanceof pudlHelper) {
			return $this->_value($identifiers);
		}

		//PARSE OUT STRING
		$dynamic	= explode('#', $identifiers);
		$list		= explode('.', $dynamic[0]);

		//VERIFY TOTAL NUMBER OF PARTS
		if (count($dynamic) > 2) throw new pudlException(
			'Wrong column format for dynamic column'
		);

		//CLEAN UP TABLE AND COLUMN NAMES
		foreach ($list as &$item) {
			$item = trim($item);
			if (!strlen($item)) throw new pudlException('Wrong column name');
		} unset($item);

		//PROCESS TABLE NAME
		if ($prefix !== false  &&  $this->prefix !== false) {
			$table = array_pop($list);
			if (substr($table, 0, 5) === 'pudl_') {
				$table = $this->prefix . substr($table, 5);
			}
			$list[] = $table;
		}

		//CLEAN UP EACH PART OF THE IDENTIFIER
		foreach ($list as &$item) $item = $this->identifier($item);
		unset($item);

		//EARLY OUT IF WE ARE NOT IN A DYNAMIC COLUMN
		$return		= implode('.', $list);
		if (count($dynamic) === 1) return $return;


		//PARSE OUT DATA TYPE
		$parts		= explode(':', $dynamic[1]);
		if (count($parts) !== 2) throw new pudlException(
			'Wrong column format for dynamic column'
		);

		//SEPARATE AND VERIFY LENGTH OF EACH SECTION
		$items		= explode('.', $parts[0]);
		foreach ($items as &$item) {
			$item = trim($item);
			if (!strlen($item)) throw new pudlException(
				'Wrong column name for dynamic column'
			);
		} unset($item);

		//RECURSIVELY GENERATE COLUMN_GET FUNCTIONS
		while (count($items)) {
			$return	= 'COLUMN_GET(' . $return . ', '
					. $this->_value( array_shift($items) ) . ' AS '
					. (count($items) ? 'BINARY' : $this->dynamic_type($parts[1])) . ')';
		}

		return $return;
	}



	public function _table($table) {
		return $this->identifiers($table, true);
	}



	protected function _tables($table) {
		if ($table === false)		return;
		if (is_string($table))		return ' FROM ' . $this->_table($table);
		if (!pudl_array($table))	return $this->_invalidType($value, 'table');

		$query = '';
		foreach ($table as $key => $value) {
			if (strlen($query)) $query .= ', ';

			if (!pudl_array($value)) {
				if ($value instanceof pudlStringResult) {
					$query .= (string) $value;
				} else {
					$query .= $this->_table($value);
				}
				if (is_string($key)) $query .= ' AS ' . $this->identifier($key);

			} else {
				$query .= $this->_table(reset($value));
				if (is_string($key)) $query .= ' AS ' . $this->identifier($key);
				foreach ($value as $join) {
					if (!empty($join['join'])) {
						$query .= $this->_joinTable($join['join'], false);
					} else if (!empty($join['cross'])) {
						$query .= $this->_joinTable($join['cross'], 'CROSS');
					} else if (!empty($join['left'])) {
						$query .= $this->_joinTable($join['left'], 'LEFT');
					} else if (!empty($join['right'])) {
						$query .= $this->_joinTable($join['right'], 'RIGHT');
					} else if (!empty($join['natural'])) {
						$query .= $this->_joinTable($join['natural'], 'NATURAL');
					} else if (!empty($join['inner'])) {
						$query .= $this->_joinTable($join['inner'], 'INNER');
					} else if (!empty($join['outer'])) {
						$query .= $this->_joinTable($join['outer'], 'OUTER');
					} else if (!empty($join['hack'])) {
						$query .= ' LEFT JOIN (' . $join['hack'] . ')';
					}

					if (!empty($join['clause'])) {
						$query .= $this->_clause($join['clause'], 'ON');
					} else if (!empty($join['on'])) {
						$query .= $this->_clause($join['on'], 'ON');
					} else if (!empty($join['using'])) {
						$query .= $this->_joinUsing($join['using']);
					}
				}
			}
		}

		return ' FROM ' . $query;
	}



	protected function _clause($clause, $type='WHERE') {
		if ($clause === false)	return '';

		if ($clause instanceof pudlStringResult) return (string) $clause;

		if ($clause instanceof pudlId) {
			return ' ' . $type . ' (' . $this->_clauseRecurse($clause->pudlId()) .')';
		}

		if (is_array($clause)  ||  is_object($clause)) {
			if (empty($clause))	return '';
			return ' ' . $type . ' (' . $this->_clauseRecurse($clause) .')';
		}

		return ' ' . $type . ' (' . $clause . ')';
	}



	protected function _order($order) {
		if (is_string($order)) return ' ORDER BY ' . $order;
		if (!is_array($order)  &&  !is_object($order)) return '';
		if ($order instanceof pudlStringResult) return (string) $order;
		if (empty($order)) return '';
		return ' ORDER BY ' . $this->_clauseRecurse($order,', ');
	}



	protected function _group($group) {
		if ($group === false)	return '';
		if ($group instanceof pudlStringResult) return (string) $group;
		if (is_array($group))	return ' GROUP BY ' . $this->_clauseRecurse($group,', ');
		if (is_object($group))	return ' GROUP BY ' . $this->_clauseRecurse($group,', ');
		return ' GROUP BY ' . $group;
	}



	private function _clauseRecurse($clause, $joiner=' AND ') {
		static $depth = 0;
		$query = '';

		if ($depth > 31) {
			throw new pudlException('Recursion limit reached');
			return '';
		}

		if ($clause instanceof pudlAnd) {
			return $this->_clauseRecurse($clause->clause, $clause->joiner);
		}

		if ($clause instanceof pudlColumn  &&  $clause->args) {
			if (is_string($clause->column)) {
				$query		.=	$this->identifiers($clause->column);
			} else {
				$query		.=	$this->_value($clause->column);
			}
			$clause			 =	$clause->value;
			$query			.=	$this->_clauseEquals($clause);
			return $query	.	$this->_value($clause);
		}

		if ($clause instanceof pudlEquals  &&  $clause->compare !== false) {
			$query			.=	$this->_value($clause->compare);
			$query			.=	$this->_clauseEquals($clause);
			if (!($clause instanceof pudlBetween)) $clause = $clause->value;
			return $query	.	$this->_value($clause);
		}

		if ($clause instanceof pudlHelper) {
			return $query	.	$this->_value($clause);
		}

		$depth++;
		foreach ($clause as $key => $value) {
			if (is_int($key)  &&  $value==='') continue;

			if (strlen($query)) $query .= $joiner;

			if ($value instanceof pudlFloat) {
				$value->column = $key;

			} else if (is_string($key)) {
				$query			.= $this->identifiers($key);
				$query			.= $this->_clauseEquals($value);
				if (pudl_array($value)) continue;

			} else if ($value instanceof pudlColumn  &&  $value->args) {
				$key			 = ''; //FORCE KEY TO STRING TYPE FOR _VALUE
				if (is_string($value->column)) {
					$query		.= $this->identifiers($value->column);
				} else {
					$query		.= $this->_value($value->column);
				}
				$value			 = $value->value;
				$query			.= $this->_clauseEquals($value);
				if (pudl_array($value)) continue;

			} else if ($value instanceof pudlAnd) {
				$query .= '(' . $this->_clauseRecurse($value->clause, $value->joiner) . ')';
				continue;

			} else if ($value instanceof pudlEquals  &&  $value->compare !== false) {
				$key			 = ''; //FORCE KEY TO STRING TYPE FOR _VALUE
				$query			.= $this->_value($value->compare);
				$query			.= $this->_clauseEquals($value);
				if (!($value instanceof pudlBetween)) $value = $value->value;
			}

			$new = $this->_value($value, is_string($key), is_string($key));

			if ($new !== false) {
				$query .= $new;

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ' AND ') {
				$query .= '(' . $this->_clauseRecurse($value, ' OR ') . ')';

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ' OR ') {
				$query .= '(' . $this->_clauseRecurse($value, ' AND ') . ')';

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ', ') {
				$query .= $this->_clauseRecurse($value, $joiner);

			} else {
				return $this->_invalidType($value, 'clause');
			}
		}

		$depth--;
		return $query;
	}



	private function _clauseEquals($value) {
		if ($value instanceof pudlEquals) {
			if (pudl_array($value->value)) {
				if ($value->equals == '=')	return ' IN ';
				if ($value->equals == '!=')	return ' NOT IN ';
			}
			return $value->equals;
		}

		if ($value instanceof pudlStringResult) return $value->type;

		if (pudl_array($value)) return ' IN (' . $this->_inSet($value) . ')';

		if (is_float($value)  &&  (is_nan($value)  ||  is_infinite($value))) return '';

		if (!is_null($value)) return '=';

		return '';
	}



	protected function _clauseId($column, $id=false) {
		if ($id === false  &&  $column instanceof pudlId) {
			$value	= $column->pudlId();
			$this->_requireTrue($value, 'Object retuned invalid value from pudlId');
			return $value;
		}

		if ($id instanceof pudlId) {
			$value	= $id->pudlId();
			if (is_array($value)  &&  (count($value)  ===  1)  &&  (key($value)  === $column)) {
				return $value;
			}<commit_msg>Fixing regressions with exception generation<commit_after><?php


trait pudlQuery {


	public function escape($value) {
		switch (true) {
			case is_int($value):
			case is_float($value):
			case is_null($value):
			case is_bool($value):
				return $value;
		}

		return str_replace(
			['\\',		"\0",	"\x08",	"\x26",	"'",	'"',	"\n",	"\r",	"\t"],
			['\\\\',	'\0',	'\b',	'\Z',	"\'",	'\"',	'\n',	'\r',	'\t'],
			(string)$value
		);
	}



	public function likeEscape($value) {
		return addcslashes($this->escape($value), '%_');
	}



	public function setEscape($value) {
		return str_replace(',', '', $value);
	}



	protected function _cache() {
		return '';
	}



	public function _value($value, $quote=true, $isnull=false) {
		static $depth = 0;
		$query = false;

		if ($depth++ > 31) {
			throw new pudlException('Recursion limit reached');
			return $query;
		}

		switch (true) {

			//THIS IS FOR AND/OR RECUSION, HANDLED ELSEWHERE
			//IN THIS CASE, DO NOTHING!
			case is_array($value): break;


			case is_int($value):
			case is_float($value):
				if (is_nan($value)  ||  is_infinite($value)) {
					$query = $isnull ? ' IS NULL' : 'NULL';
				} else {
					$query = $value;
				}
			break;


			case is_string($value):
				$query = $quote ? "'".$this->escape($value)."'" : $value;
			break;


			case is_bool($value):
				$query = $value ? 'TRUE' : 'FALSE';
			break;


			case is_null($value):
				$query = $isnull ? ' IS NULL' : 'NULL';
			break;


			case $value instanceof pudlValue:
				$query = $value->pudlValue($this, $quote);
			break;


			case is_callable([$value, '__toString']):
				$query = $quote
					? "'" . $this->escape((string)$value) . "'"
					: (string)$value;
			break;


			default:
				return $this->_invalidType($value);
		}


		$depth--;
		return $query;
	}



	private function _regexp($value) {
		$query = '';
		if (!pudl_array($value)) $value = [$value];
		foreach ($value as $item) {
			$query .= is_string($item) ?
				$this->escape(preg_quote($item)) :
				$this->_value($item, false);
		}
		return "'".$query."'";
	}



	protected function _column($column) {
		if ($column instanceof pudlId) {
			$column = key( $column->pudlId() );
		}

		if (!pudl_array($column)) {
			switch ($column) {
				case '':
				case '*':
				case null:
				case false:
					return '*';
			}
			return $this->_value($column, false);
		}

		$query = '';
		foreach ($column as $key => $value) {
			if (strlen($query)) $query .= ', ';
			if (is_string($key)) {
				if (is_string($value)) {
					$query .= $this->identifiers($value);
				} else {
					$query .= $this->_value($value, true);
				}
				$query .= ' AS ' . $this->identifier($key);
			} else {
				$query .= $this->_value($value, is_string($key));
			}
		}

		return $query;
	}



	public function identifier($identifier) {
		if ($identifier instanceof pudlHelper) {
			return $this->_value($identifier);
		}

		return $this->identifier . str_replace(
			$this->identifier,
			$this->identifier.$this->identifier,
			$identifier
		) . $this->identifier;
	}



	public function identifiers($identifiers, $prefix=false) {
		if ($identifiers === false) return '';

		//PUDL HELPERS HAVE SPECIAL HANDLERS
		if ($identifiers instanceof pudlHelper) {
			return $this->_value($identifiers);
		}

		//PARSE OUT STRING
		$dynamic	= explode('#', $identifiers);
		$list		= explode('.', $dynamic[0]);

		//VERIFY TOTAL NUMBER OF PARTS
		if (count($dynamic) > 2) throw new pudlException(
			'Wrong column format for dynamic column'
		);

		//CLEAN UP TABLE AND COLUMN NAMES
		foreach ($list as &$item) {
			$item = trim($item);
			if (!strlen($item)) throw new pudlException('Wrong column name');
		} unset($item);

		//PROCESS TABLE NAME
		if ($prefix !== false  &&  $this->prefix !== false) {
			$table = array_pop($list);
			if (substr($table, 0, 5) === 'pudl_') {
				$table = $this->prefix . substr($table, 5);
			}
			$list[] = $table;
		}

		//CLEAN UP EACH PART OF THE IDENTIFIER
		foreach ($list as &$item) $item = $this->identifier($item);
		unset($item);

		//EARLY OUT IF WE ARE NOT IN A DYNAMIC COLUMN
		$return		= implode('.', $list);
		if (count($dynamic) === 1) return $return;


		//PARSE OUT DATA TYPE
		$parts		= explode(':', $dynamic[1]);
		if (count($parts) !== 2) throw new pudlException(
			'Wrong column format for dynamic column'
		);

		//SEPARATE AND VERIFY LENGTH OF EACH SECTION
		$items		= explode('.', $parts[0]);
		foreach ($items as &$item) {
			$item = trim($item);
			if (!strlen($item)) throw new pudlException(
				'Wrong column name for dynamic column'
			);
		} unset($item);

		//RECURSIVELY GENERATE COLUMN_GET FUNCTIONS
		while (count($items)) {
			$return	= 'COLUMN_GET(' . $return . ', '
					. $this->_value( array_shift($items) ) . ' AS '
					. (count($items) ? 'BINARY' : $this->dynamic_type($parts[1])) . ')';
		}

		return $return;
	}



	public function _table($table) {
		return $this->identifiers($table, true);
	}



	protected function _tables($table) {
		if ($table === false)		return;
		if (is_string($table))		return ' FROM ' . $this->_table($table);
		if (!pudl_array($table))	return $this->_invalidType($value, 'table');

		$query = '';
		foreach ($table as $key => $value) {
			if (strlen($query)) $query .= ', ';

			if (!pudl_array($value)) {
				if ($value instanceof pudlStringResult) {
					$query .= (string) $value;
				} else {
					$query .= $this->_table($value);
				}
				if (is_string($key)) $query .= ' AS ' . $this->identifier($key);

			} else {
				$query .= $this->_table(reset($value));
				if (is_string($key)) $query .= ' AS ' . $this->identifier($key);
				foreach ($value as $join) {
					if (!empty($join['join'])) {
						$query .= $this->_joinTable($join['join'], false);
					} else if (!empty($join['cross'])) {
						$query .= $this->_joinTable($join['cross'], 'CROSS');
					} else if (!empty($join['left'])) {
						$query .= $this->_joinTable($join['left'], 'LEFT');
					} else if (!empty($join['right'])) {
						$query .= $this->_joinTable($join['right'], 'RIGHT');
					} else if (!empty($join['natural'])) {
						$query .= $this->_joinTable($join['natural'], 'NATURAL');
					} else if (!empty($join['inner'])) {
						$query .= $this->_joinTable($join['inner'], 'INNER');
					} else if (!empty($join['outer'])) {
						$query .= $this->_joinTable($join['outer'], 'OUTER');
					} else if (!empty($join['hack'])) {
						$query .= ' LEFT JOIN (' . $join['hack'] . ')';
					}

					if (!empty($join['clause'])) {
						$query .= $this->_clause($join['clause'], 'ON');
					} else if (!empty($join['on'])) {
						$query .= $this->_clause($join['on'], 'ON');
					} else if (!empty($join['using'])) {
						$query .= $this->_joinUsing($join['using']);
					}
				}
			}
		}

		return ' FROM ' . $query;
	}



	protected function _clause($clause, $type='WHERE') {
		if ($clause === false)	return '';

		if ($clause instanceof pudlStringResult) return (string) $clause;

		if ($clause instanceof pudlId) {
			return ' ' . $type . ' (' . $this->_clauseRecurse($clause->pudlId()) .')';
		}

		if (is_array($clause)  ||  is_object($clause)) {
			if (empty($clause))	return '';
			return ' ' . $type . ' (' . $this->_clauseRecurse($clause) .')';
		}

		return ' ' . $type . ' (' . $clause . ')';
	}



	protected function _order($order) {
		if (is_string($order)) return ' ORDER BY ' . $order;
		if (!is_array($order)  &&  !is_object($order)) return '';
		if ($order instanceof pudlStringResult) return (string) $order;
		if (empty($order)) return '';
		return ' ORDER BY ' . $this->_clauseRecurse($order,', ');
	}



	protected function _group($group) {
		if ($group === false)	return '';
		if ($group instanceof pudlStringResult) return (string) $group;
		if (is_array($group))	return ' GROUP BY ' . $this->_clauseRecurse($group,', ');
		if (is_object($group))	return ' GROUP BY ' . $this->_clauseRecurse($group,', ');
		return ' GROUP BY ' . $group;
	}



	private function _clauseRecurse($clause, $joiner=' AND ') {
		static $depth = 0;
		$query = '';

		if ($depth > 31) {
			throw new pudlException('Recursion limit reached');
			return '';
		}

		if ($clause instanceof pudlAnd) {
			return $this->_clauseRecurse($clause->clause, $clause->joiner);
		}

		if ($clause instanceof pudlColumn  &&  $clause->args) {
			if (is_string($clause->column)) {
				$query		.=	$this->identifiers($clause->column);
			} else {
				$query		.=	$this->_value($clause->column);
			}
			$clause			 =	$clause->value;
			$query			.=	$this->_clauseEquals($clause);
			return $query	.	$this->_value($clause);
		}

		if ($clause instanceof pudlEquals  &&  $clause->compare !== false) {
			$query			.=	$this->_value($clause->compare);
			$query			.=	$this->_clauseEquals($clause);
			if (!($clause instanceof pudlBetween)) $clause = $clause->value;
			return $query	.	$this->_value($clause);
		}

		if ($clause instanceof pudlHelper) {
			return $query	.	$this->_value($clause);
		}

		$depth++;
		foreach ($clause as $key => $value) {
			if (is_int($key)  &&  $value==='') continue;

			if (strlen($query)) $query .= $joiner;

			if ($value instanceof pudlFloat) {
				$value->column = $key;

			} else if (is_string($key)) {
				$query			.= $this->identifiers($key);
				$query			.= $this->_clauseEquals($value);
				if (pudl_array($value)) continue;

			} else if ($value instanceof pudlColumn  &&  $value->args) {
				$key			 = ''; //FORCE KEY TO STRING TYPE FOR _VALUE
				if (is_string($value->column)) {
					$query		.= $this->identifiers($value->column);
				} else {
					$query		.= $this->_value($value->column);
				}
				$value			 = $value->value;
				$query			.= $this->_clauseEquals($value);
				if (pudl_array($value)) continue;

			} else if ($value instanceof pudlAnd) {
				$query .= '(' . $this->_clauseRecurse($value->clause, $value->joiner) . ')';
				continue;

			} else if ($value instanceof pudlEquals  &&  $value->compare !== false) {
				$key			 = ''; //FORCE KEY TO STRING TYPE FOR _VALUE
				$query			.= $this->_value($value->compare);
				$query			.= $this->_clauseEquals($value);
				if (!($value instanceof pudlBetween)) $value = $value->value;
			}

			$new = $this->_value($value, is_string($key), is_string($key));

			if ($new !== false) {
				$query .= $new;

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ' AND ') {
				$query .= '(' . $this->_clauseRecurse($value, ' OR ') . ')';

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ' OR ') {
				$query .= '(' . $this->_clauseRecurse($value, ' AND ') . ')';

			} else if ((is_array($value)  ||  is_object($value))  &&  $joiner === ', ') {
				$query .= $this->_clauseRecurse($value, $joiner);

			} else {
				return $this->_invalidType($value, 'clause');
			}
		}

		$depth--;
		return $query;
	}



	private function _clauseEquals($value) {
		if ($value instanceof pudlEquals) {
			if (pudl_array($value->value)) {
				if ($value->equals == '=')	return ' IN ';
				if ($value->equals == '!=')	return ' NOT IN ';
			}
			return $value->equals;
		}

		if ($value instanceof pudlStringResult) return $value->type;

		if (pudl_array($value)) return ' IN (' . $this->_inSet($value) . ')';

		if (is_float($value)  &&  (is_nan($value)  ||  is_infinite($value))) return '';

		if (!is_null($value)) return '=';

		return '';
	}



	protected function _clauseId($column, $id=false) {
		if ($id === false) {
			if ($column instanceof pudlId) {
				$value	= $column->pudlId();
				$this->_requireTrue($value, 'Object retuned invalid value from pudlId');
				return $value;
			}
			throw new pudlException(is_object($column)
				? 'Undefined method: ' . get_class($column) . '::pudlId'
				: 'Invalid data type for object: ' . gettype($column)
			);
			return false;
		}

		if ($id instanceof pudlId) {
			$value	= $id->pudlId();
			if (is_array($value)  &&  (count($value)  ===  1)  &&  (key($value)  === $column)) {
				return $value;
			}
{'fraction_non_alphanumeric': 0.20884895745041532, 'fraction_numerical': 0.0019494829632141042, 'mean_word_length': 3.153670128498504, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 215, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '728946', 'n_tokens_mistral': 10008, 'n_tokens_neox': 8249, 'n_words': 1844}