Automattic / HyperDB

HyperDB is an advanced database class that supports replication, failover, load balancing, and partitioning.
101 stars 22 forks source link

get_table_from_query() fail to return correct table name on long query string #139

Open hesahesa opened 1 year ago

hesahesa commented 1 year ago

When we call hyperdb's get_table_from_query() function with a long SQL string (more than 1500 chars), the query fails to return the table name and returns false instead.

This is inconsistent with the behavior of the WP Core wpdb's get_table_from_query() that successfully return the table name. Although in the hyperdb's get_table_from_query() will call the wpdb's get_table_from_query() as a fallback, it seems that the parameter passed to the wpdb is the truncated version of the query string, not the original query string.

The impact of this is that if we have an SRTM setting for some tables, returning false in this function will render the SRTM useless.

Step to reproduce:

$q = "SELECT wc_order.id as id, wc_order.status as status, wc_order.type as type, wc_order.currency as currency, wc_order.tax_amount as cart_tax, wc_order.total_amount as total, wc_order.customer_id as customer_id, wc_order.billing_email as billing_email, wc_order.date_created_gmt as date_created, wc_order.date_updated_gmt as date_modified, wc_order.parent_order_id as parent_id, wc_order.payment_method as payment_method, wc_order.payment_method_title as payment_method_title, wc_order.ip_address as customer_ip_address, wc_order.transaction_id as transaction_id, wc_order.user_agent as customer_user_agent, wc_order.customer_note as customer_note, address_billing.id as address_billing_id, address_billing.order_id as address_billing_order_id, address_billing.address_type as address_billing_address_type, address_billing.first_name as billing_first_name, address_billing.last_name as billing_last_name, address_billing.company as billing_company, address_billing.address_1 as billing_address_1, address_billing.address_2 as billing_address_2, address_billing.city as billing_city, address_billing.state as billing_state, address_billing.postcode as billing_postcode, address_billing.country as billing_country, address_billing.email as billing_email, address_billing.phone as billing_phone, address_shipping.id as address_shipping_id, address_shipping.order_id as address_shipping_order_id, address_shipping.address_type as address_shipping_address_type, address_shipping.first_name as shipping_first_name, address_shipping.last_name as shipping_last_name, address_shipping.company as shipping_company, address_shipping.address_1 as shipping_address_1, address_shipping.address_2 as shipping_address_2, address_shipping.city as shipping_city, address_shipping.state as shipping_state, address_shipping.postcode as shipping_postcode, address_shipping.country as shipping_country, address_shipping.email as address_shipping_email, address_shipping.phone as shipping_phone, order_operational_data.id as order_operational_data_id, order_operational_data.order_id as order_operational_data_order_id, order_operational_data.created_via as created_via, order_operational_data.woocommerce_version as version, order_operational_data.prices_include_tax as prices_include_tax, order_operational_data.coupon_usages_are_counted as recorded_coupon_usage_counts, order_operational_data.download_permission_granted as download_permissions_granted, order_operational_data.cart_hash as cart_hash, order_operational_data.new_order_email_sent as new_order_email_sent, order_operational_data.order_key as order_key, order_operational_data.order_stock_reduced as order_stock_reduced, order_operational_data.date_paid_gmt as date_paid, order_operational_data.date_completed_gmt as date_completed, order_operational_data.shipping_tax_amount as shipping_tax, order_operational_data.shipping_total_amount as shipping_total, order_operational_data.discount_tax_amount as discount_tax, order_operational_data.discount_total_amount as discount_total, order_operational_data.recorded_sales as recorded_sales FROM wp_wc_orders wc_order LEFT JOIN wp_wc_order_addresses address_billing ON address_billing.order_id = wc_order.id AND address_billing.address_type = 'billing' LEFT JOIN wp_wc_order_addresses address_shipping ON address_shipping.order_id = wc_order.id AND address_shipping.address_type = 'shipping' LEFT JOIN wp_wc_order_operational_data order_operational_data ON order_operational_data.order_id = wc_order.id WHERE wc_order.id in ( 2334 )"

$call_protected = function () use ( $q ) { return $this->get_table_from_query( $q ); };

$wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );

$hyperdb = new hyperdb();

$wpdb_result = $call_protected->call( $wpdb ); // this returns "wp_wc_orders"

$hyperdb_result = $call_protected->call( $hyperdb ); // this returns false

Expectation: