function _db_mangle_query(&$databases, $qstruct) { global $SCHEMA; global $SYNTAX_QUERY; if ($list = @$qstruct["UNION"]) { foreach ($list as $alias => $subq) { $qstruct[$alias] = _db_mangle_query($databases, $subq); } return $qstruct; } if ($error = db_check_syntax($qstruct, $SYNTAX_QUERY)) { echo "qstruct error: {$error}<br>\n"; global $debug; if ($debug) { echo "syntax: "; print_r($qstruct); echo "<br>\n"; } return null; } // make a homogenous array syntax out of comma-separated strings $h**o = _db_homogenize($qstruct); $h**o = _db_add_schema($h**o); $h**o = _db_mangle_joins($h**o); // check whether all tables are on the same database foreach ($h**o["BASE_TABLE"] as $table) { $database = _db_database($table); $databases[$database] = true; } if (count($databases) > 1) { die("NYI: connot treat queries spanning multiple databases\n"); } return $h**o; }
function _mysql_make_boolean($table, $field, $value, $use_or) { global $RAW_DOTID; global $ERROR; global $debug; // check nested conditions if (!is_string($field) && is_array($value)) { // toggle and<->or $subres = _mysql_make_where($table, $value, !$use_or); return "({$subres})"; } // check unary operators $regex = "/^\\s*?(exists|not(?:\\s+exists)?)\\s*\$/"; if (preg_match($regex, $field, $matches)) { $op = $matches[1]; if (preg_match("/exists/", $op)) { $dummy = array(); $subres = mysql_make_query($dummy, $value); } else { $subres = _mysql_make_where($table, $value, $use_or); } return "{$op} ({$subres})"; } // check binary operators $op = "="; $regex = "/^(\\\\?{$RAW_DOTID})?\\s*(?:(=|<>|<|>|<=|>=|!|@|%| like| rlike| in| not in)\\s*({$RAW_DOTID})?)?\$/"; $old_field = $field; if (!preg_match($regex, $field, $matches)) { $ERROR = "bad field expression '{$field}'"; return "/*bad field expression '{$field}'*/false"; } $field = $matches[1]; if (!$field) { // pure operator if (!@$matches[2]) { die("bad single operator"); } $op = trim($matches[2]); $arg1 = $value[0]; $arg2 = $value[1]; $value1 = _db_homogenize($arg1); $value2 = _db_homogenize($arg2); $dummy = array(); $subquery1 = mysql_make_query($dummy, $value1); $dummy = array(); $subquery2 = mysql_make_query($dummy, $value2); $res = "({$subquery1}) {$op} ({$subquery2})"; return $res; } $realfield = _db_realname($table, $field); if (!$realfield) { die("cannot find field '{$field}' in table '{$table}'\n"); } $sql_value = null; if (@$matches[3]) { $sql_value = $matches[3]; $op = trim($matches[2]); } elseif (is_null($value)) { $op = "!"; } else { if (@$matches[2]) { $op = trim($matches[2]); if (is_array($value) && !@$value["TABLE"] && !@$value["UNION"]) { // multiple conditions (indicated by absence of TABLE or UNION) $res = ""; foreach ($value as $item) { if ($res) { if ($use_or) { $res .= " or "; } else { $res .= " and "; } } // treat the same as if the operator had been repeated. $res .= _mysql_make_boolean($table, $old_field, $item, $use_or); } return $res; } } if (is_array($value)) { // sub-sql statement (indicated by _absence_ of operator) if (!@$value["TABLE"] && !@$value["UNION"]) { // test against most sloppiness print_r($value); die("field '{$old_field}': badly formed sub-sql statement\n"); } if ($debug) { echo "start homogenizing: "; print_r($value); echo "<br>\n"; } $value = _db_homogenize($value); $dummy = array(); $subquery = mysql_make_query($dummy, $value); $sql_value = "({$subquery})"; } else { $sql_value = db_esc_sql($value); } } if ($op == "@") { $res = "{$realfield} is not null"; } elseif ($op == "%" || $op == "like") { $res = "{$realfield} like {$sql_value}"; } elseif ($op == "!") { $res = "{$realfield} is null"; } else { $res = "{$realfield} {$op} {$sql_value}"; } return $res; }