WP_Meta_Query::get_sql_for_query()protectedWP 4.1.0

Generates SQL clauses for a single query array.

If nested subqueries are found, this method recurses the tree to produce the properly nested SQL.

Method of the class: WP_Meta_Query{}

No Hooks.

Return

String[]. Array containing JOIN and WHERE SQL clauses to append to a single query array.

Usage

// protected - for code of main (parent) or child class
$result = $this->get_sql_for_query( $query, $depth );
$query(array) (required) (passed by reference — &)
Query to parse (passed by reference).
$depth(int)
Number of tree levels deep we currently are. Used to calculate indentation.

Changelog

Since 4.1.0 Introduced.

WP_Meta_Query::get_sql_for_query() code WP 6.4.3

protected function get_sql_for_query( &$query, $depth = 0 ) {
	$sql_chunks = array(
		'join'  => array(),
		'where' => array(),
	);

	$sql = array(
		'join'  => '',
		'where' => '',
	);

	$indent = '';
	for ( $i = 0; $i < $depth; $i++ ) {
		$indent .= '  ';
	}

	foreach ( $query as $key => &$clause ) {
		if ( 'relation' === $key ) {
			$relation = $query['relation'];
		} elseif ( is_array( $clause ) ) {

			// This is a first-order clause.
			if ( $this->is_first_order_clause( $clause ) ) {
				$clause_sql = $this->get_sql_for_clause( $clause, $query, $key );

				$where_count = count( $clause_sql['where'] );
				if ( ! $where_count ) {
					$sql_chunks['where'][] = '';
				} elseif ( 1 === $where_count ) {
					$sql_chunks['where'][] = $clause_sql['where'][0];
				} else {
					$sql_chunks['where'][] = '( ' . implode( ' AND ', $clause_sql['where'] ) . ' )';
				}

				$sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] );
				// This is a subquery, so we recurse.
			} else {
				$clause_sql = $this->get_sql_for_query( $clause, $depth + 1 );

				$sql_chunks['where'][] = $clause_sql['where'];
				$sql_chunks['join'][]  = $clause_sql['join'];
			}
		}
	}

	// Filter to remove empties.
	$sql_chunks['join']  = array_filter( $sql_chunks['join'] );
	$sql_chunks['where'] = array_filter( $sql_chunks['where'] );

	if ( empty( $relation ) ) {
		$relation = 'AND';
	}

	// Filter duplicate JOIN clauses and combine into a single string.
	if ( ! empty( $sql_chunks['join'] ) ) {
		$sql['join'] = implode( ' ', array_unique( $sql_chunks['join'] ) );
	}

	// Generate a single WHERE clause with proper brackets and indentation.
	if ( ! empty( $sql_chunks['where'] ) ) {
		$sql['where'] = '( ' . "\n  " . $indent . implode( ' ' . "\n  " . $indent . $relation . ' ' . "\n  " . $indent, $sql_chunks['where'] ) . "\n" . $indent . ')';
	}

	return $sql;
}