Example #1
0
/**
 * @brief Adds the SELECT clause to a given node from the SQL tree
 * @param sqlTree the SQL tree which is rewritten
 * @param table currently treated table
 * @param toThisNode the node where the SELECT clause is added to
 * @param tableList the sorted table list
 * @param recLevel current recursion level
 * 
 * Takes the SELECT clause from sqlTree and adds it to the current node. 
 */
function PHPSQLaddOuterQuerySelect(&$sqlTree, &$table, &$toThisNode, $tableList, $recLevel)
{
    if (!array_key_exists('SELECT', $sqlTree)) {
        return;
    }
    #if the SELECT key does not exist in the target tree, create it
    if (!array_key_exists('SELECT', $toThisNode)) {
        $toThisNode['SELECT'] = array();
    }
    if (hasAlias($table)) {
        $tblAlias = extractTableAlias($table['node']);
    } else {
        $tblAlias = false;
    }
    $tblDb = extractDbName($table['node']);
    $tblName = extractTableName($table['node']);
    #collect all columns from the sql tree
    $partList = array();
    PHPSQLcollectColumns($sqlTree, $tblDb, $tblName, trim($tblAlias, '`'), $partList, $tableList, $recLevel);
    foreach ($partList as $node) {
        $nodeCopy = $node;
        $nodeCopy['base_expr'] = getBaseExpr($nodeCopy);
        if (!hasAlias($nodeCopy) && isColref($nodeCopy) && $nodeCopy['base_expr'] !== "*") {
            $nodeCopy['alias'] = createAliasNode(array(implodeNoQuotes($nodeCopy['no_quotes'])));
        }
        array_push($toThisNode['SELECT'], $nodeCopy);
        $key = array_search($node, $sqlTree['SELECT']);
        unset($sqlTree['SELECT'][$key]);
    }
    //if this is recLevel = 0, add all remaining columns as well
    if ($recLevel == 0) {
        foreach ($sqlTree['SELECT'] as $node) {
            //only colrefs are not yet considered here, remaining stuff has been caputred by collectColumns
            if (isColref($node)) {
                array_push($toThisNode['SELECT'], $node);
            }
        }
        $sqlTree['SELECT'] = array();
    }
    #in order for the joins to work properly, collect all the variables that
    #somehow participate in the where
    if (empty($sqlTree['WHERE'])) {
        return;
    }
    $tmpList1 = PHPSQLgetAllColsFromWhere($sqlTree['WHERE'], $tblAlias, false);
    $tmpList2 = PHPSQLgetAllColsFromWhere($sqlTree['WHERE'], $tblName, true);
    //this handles (crudely) the case, when no alias is given to the DB
    if ($table['name'] === extractTableAlias($table['node'])) {
        $tmpList3 = PHPSQLgetAllColsFromWhere($sqlTree['WHERE'], "", true);
        $tmpList2 = array_merge($tmpList2, $tmpList3);
    }
    if ($tblAlias === $tblName) {
        $listOfWhereCols = $tmpList1;
    } else {
        $listOfWhereCols = array_merge($tmpList1, $tmpList2);
    }
    foreach ($listOfWhereCols as $cols) {
        $find = false;
        foreach ($toThisNode['SELECT'] as &$node) {
            if (columnIsEqual($node, $cols)) {
                $find = true;
                break;
            }
        }
        if ($find === false) {
            #mark this select as comming from a where
            $cols['where_col'] = true;
            $cols['base_expr'] = getBaseExpr($cols);
            if (!hasAlias($cols) && isColref($cols) && $cols['base_expr'] !== "*") {
                $cols['alias'] = createAliasNode(array(implodeNoQuotes($cols['no_quotes'])));
            }
            array_push($toThisNode['SELECT'], $cols);
        }
    }
}
Example #2
0
/**
 * @brief Add all columns to the SELECT tree
 * @param sqlTree SQL parser tree node of complete query/subquery
 * @param mysqlConn a properly initialised MySQLI/MySQLII connection to the DB
 * @param zendAdapter a valid ZEND DB adapter
 * 
 * This function will evaluate the all the tables that need SQL * attribute substitution.
 * The database is queried to retrieve a complete list of columns of each table and the
 * approperiate SELECT colref nodes are added to the SQL parser tree. The SQL * attribute
 * is removed from the sqlTree SELECT node.
 */
function _parseSqlAll_SELECT(&$sqlTree, $mysqlConn = false, $zendAdapter = false)
{
    if (!is_array($sqlTree) || !array_key_exists('SELECT', $sqlTree)) {
        return;
    }
    $table = false;
    $selectCpy = $sqlTree['SELECT'];
    $sqlTree['SELECT'] = array();
    foreach ($selectCpy as &$node) {
        if (strpos($node['base_expr'], "*") !== false && $node['sub_tree'] === false) {
            //we have found an all operator and need to find the corresponding
            //table to look things up
            $tableFullName = false;
            $dbName = extractDbName($node);
            $tableName = extractTableName($node);
            $colName = extractColumnName($node);
            if ($dbName !== false) {
                $tableFullName = "`" . $dbName . "`.`" . $tableName . "`";
            } else {
                if ($tableName !== false) {
                    $tableFullName = "`" . $tableName . "`";
                }
            }
            $table = array();
            $alias = array();
            if ($tableFullName === false) {
                //add everything *ed from all tables to this query
                foreach ($sqlTree['FROM'] as $fromNode) {
                    if (isTable($fromNode)) {
                        $table[] = $fromNode['table'];
                        if (!hasAlias($fromNode)) {
                            $alias[] = $fromNode['table'];
                        } else {
                            $alias[] = $fromNode['alias']['name'];
                        }
                    } else {
                        if (isSubquery($fromNode)) {
                            //handle subqueries...
                            _parseSqlAll_linkSubquerySELECT($fromNode['sub_tree'], $sqlTree, $fromNode['alias']['name']);
                        }
                    }
                }
            } else {
                foreach ($sqlTree['FROM'] as $fromNode) {
                    //it could be, that the table here is actually another aliased table (which should
                    //have been processed here already, since SELECT is called last) -> link to tree
                    if (isTable($fromNode)) {
                        if (hasAlias($fromNode)) {
                            if (trim($fromNode['alias']['name'], "`") === $tableName) {
                                $table[] = $fromNode['table'];
                                break;
                            }
                        } else {
                            if ($fromNode['table'] === $tableFullName) {
                                $table[] = $fromNode['table'];
                                break;
                            }
                        }
                    } else {
                        if (isSubquery($fromNode)) {
                            if (trim($fromNode['alias']['name'], "`") === $tableName) {
                                _parseSqlAll_linkSubquerySELECT($fromNode['sub_tree'], $sqlTree, $tableName);
                                continue 2;
                            }
                        }
                    }
                }
                $alias[] = $tableFullName;
            }
            if (empty($table)) {
                continue;
            }
            //now that we know the table, we need to look up what is in there
            foreach (array_keys($table) as $key) {
                if ($mysqlConn !== false) {
                    _parseSqlAll_getColsMysqlii($sqlTree, $node, $mysqlConn, $table[$key], $alias[$key]);
                }
                if ($zendAdapter !== false) {
                    _parseSqlAll_getColsZend($sqlTree, $node, $zendAdapter, $table[$key], $alias[$key]);
                }
            }
        } else {
            array_push($sqlTree['SELECT'], $node);
        }
    }
}