protected function processExpressionList($unparsed) { $processor = new ExpressionListProcessor(); $expr = $this->removeParenthesisFromStart($unparsed); $expr = $this->splitSQLIntoTokens($expr); return $processor->process($expr); }
public function process($tokens, $select = array()) { $parsed = parent::process($tokens); foreach ($parsed as $k => $v) { if ($v['expr_type'] === ExpressionType::COLREF) { foreach ($select as $clause) { if (!$clause['alias']) { continue; } if ($clause['alias']['no_quotes'] === $v['no_quotes']) { $parsed[$k]['expr_type'] = ExpressionType::ALIAS; break; } } } } return $parsed; }
protected function processFromExpression(&$parseInfo) { $res = array(); // exchange the join types (join_type is save now, saved_join_type holds the next one) $parseInfo['join_type'] = $parseInfo['saved_join_type']; // initialized with JOIN $parseInfo['saved_join_type'] = $parseInfo['next_join_type'] ? $parseInfo['next_join_type'] : 'JOIN'; // we have a reg_expr, so we have to parse it if ($parseInfo['ref_expr'] !== false) { $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($parseInfo['ref_expr'])); // here we can get a comma separated list foreach ($unparsed as $k => $v) { if ($this->isCommaToken($v)) { $unparsed[$k] = ""; } } $processor = new ExpressionListProcessor(); $parseInfo['ref_expr'] = $processor->process($unparsed); } // there is an expression, we have to parse it if (substr(trim($parseInfo['table']), 0, 1) == '(') { $parseInfo['expression'] = $this->removeParenthesisFromStart($parseInfo['table']); if (preg_match("/^\\s*select/i", $parseInfo['expression'])) { $processor = new DefaultProcessor(); $parseInfo['sub_tree'] = $processor->process($parseInfo['expression']); $res['expr_type'] = ExpressionType::SUBQUERY; } else { $tmp = $this->splitSQLIntoTokens($parseInfo['expression']); $parseInfo['sub_tree'] = $this->process($tmp); $res['expr_type'] = ExpressionType::TABLE_EXPRESSION; } } else { $res['expr_type'] = ExpressionType::TABLE; $res['table'] = $parseInfo['table']; $res['no_quotes'] = $this->revokeQuotation($parseInfo['table']); } $res['alias'] = $parseInfo['alias']; $res['join_type'] = $parseInfo['join_type']; $res['ref_type'] = $parseInfo['ref_type']; $res['ref_clause'] = $parseInfo['ref_expr']; $res['base_expr'] = trim($parseInfo['expression']); $res['sub_tree'] = $parseInfo['sub_tree']; return $res; }
protected function processExpressionList($parsed) { $processor = new ExpressionListProcessor(); return $processor->process($parsed); }
public function process($tokens) { $base_expr = ""; $prevCategory = ""; $currCategory = ""; $expr = array(); $result = array(); $skip = 0; foreach ($tokens as $k => $token) { $trim = trim($token); $base_expr .= $token; if ($skip !== 0) { $skip--; continue; } if ($trim === "") { continue; } $upper = strtoupper($trim); switch ($upper) { case 'CONSTRAINT': $expr[] = array('expr_type' => ExpressionType::CONSTRAINT, 'base_expr' => $trim, 'sub_tree' => false); $currCategory = $prevCategory = $upper; continue 2; case 'LIKE': $expr[] = array('expr_type' => ExpressionType::LIKE, 'base_expr' => $trim); $currCategory = $prevCategory = $upper; continue 2; case 'FOREIGN': if ($prevCategory === "" || $prevCategory === "CONSTRAINT") { $expr[] = array('expr_type' => ExpressionType::FOREIGN_KEY, 'base_expr' => $trim); $currCategory = $upper; continue 2; } # else ? break; case 'PRIMARY': if ($prevCategory === "" || $prevCategory === "CONSTRAINT") { # next one is KEY $expr[] = array('expr_type' => ExpressionType::PRIMARY_KEY, 'base_expr' => $trim); $currCategory = $upper; continue 2; } # else ? break; case 'UNIQUE': if ($prevCategory === "" || $prevCategory === "CONSTRAINT") { # next one is KEY $expr[] = array('expr_type' => ExpressionType::UNIQUE_IDX, 'base_expr' => $trim); $currCategory = $upper; continue 2; } # else ? break; case 'KEY': # the next one is an index name if ($currCategory === 'PRIMARY' || $currCategory === 'FOREIGN' || $currCategory === 'UNIQUE') { $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); continue 2; } $expr[] = array('expr_type' => ExpressionType::INDEX, 'base_expr' => $trim); $currCategory = $upper; continue 2; case 'CHECK': $expr[] = array('expr_type' => ExpressionType::CHECK, 'base_expr' => $trim); $currCategory = $upper; continue 2; case 'INDEX': if ($currCategory === 'UNIQUE' || $currCategory === 'FULLTEXT' || $currCategory === 'SPATIAL') { $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); continue 2; } $expr[] = array('expr_type' => ExpressionType::INDEX, 'base_expr' => $trim); $currCategory = $upper; continue 2; case 'FULLTEXT': $expr[] = array('expr_type' => ExpressionType::FULLTEXT_IDX, 'base_expr' => $trim); $currCategory = $prevCategory = $upper; continue 2; case 'SPATIAL': $expr[] = array('expr_type' => ExpressionType::SPATIAL_IDX, 'base_expr' => $trim); $currCategory = $prevCategory = $upper; continue 2; case 'WITH': # starts an index option if ($currCategory === 'INDEX_COL_LIST') { $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = array('expr_type' => ExpressionType::INDEX_PARSER, 'base_expr' => substr($base_expr, 0, -strlen($token)), 'sub_tree' => array($option)); $base_expr = $token; $currCategory = 'INDEX_PARSER'; continue 2; } break; case 'KEY_BLOCK_SIZE': # starts an index option if ($currCategory === 'INDEX_COL_LIST') { $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = array('expr_type' => ExpressionType::INDEX_SIZE, 'base_expr' => substr($base_expr, 0, -strlen($token)), 'sub_tree' => array($option)); $base_expr = $token; $currCategory = 'INDEX_SIZE'; continue 2; } break; case 'USING': # starts an index option if ($currCategory === 'INDEX_COL_LIST' || $currCategory === 'PRIMARY') { $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = array('base_expr' => substr($base_expr, 0, -strlen($token)), 'trim' => $trim, 'category' => $currCategory, 'sub_tree' => array($option)); $base_expr = $token; $currCategory = 'INDEX_TYPE'; continue 2; } # else ? break; case 'REFERENCES': if ($currCategory === 'INDEX_COL_LIST' && $prevCategory === 'FOREIGN') { $processor = new ReferenceDefinitionProcessor(); $refs = $processor->process(array_slice($tokens, $k - 1, null, true)); $skip = $refs['till'] - $k; unset($refs['till']); $expr[] = $refs; $currCategory = $upper; } break; case 'BTREE': case 'HASH': if ($currCategory === 'INDEX_TYPE') { $last = array_pop($expr); $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = array('expr_type' => ExpressionType::INDEX_TYPE, 'base_expr' => $base_expr, 'sub_tree' => $last['sub_tree']); $base_expr = $last['base_expr'] . $base_expr; # FIXME: it could be wrong for index_type within index_option $currCategory = $last['category']; continue 2; } #else break; case '=': if ($currCategory === 'INDEX_SIZE') { # the optional character between KEY_BLOCK_SIZE and the numeric constant $last = array_pop($expr); $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = $last; continue 2; } break; case 'PARSER': if ($currCategory === 'INDEX_PARSER') { $last = array_pop($expr); $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); $expr[] = $last; continue 2; } # else? break; case ',': # this starts the next definition $type = $this->correctExpressionType($expr); $result['create-def'][] = array('expr_type' => $type, 'base_expr' => trim(substr($base_expr, 0, -strlen($token))), 'sub_tree' => $expr); $base_expr = ""; $expr = array(); break; default: switch ($currCategory) { case 'LIKE': # this is the tablename after LIKE $expr[] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim, 'base_expr' => $trim, 'no_quotes' => $this->revokeQuotation($trim)); break; case 'PRIMARY': if ($upper[0] === '(' && substr($upper, -1) === ')') { # the column list $processor = new IndexColumnListProcessor(); $cols = $processor->process($this->removeParenthesisFromStart($trim)); $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim, 'sub_tree' => $cols); $prevCategory = $currCategory; $currCategory = "INDEX_COL_LIST"; continue 3; } # else? break; case 'FOREIGN': if ($upper[0] === '(' && substr($upper, -1) === ')') { $processor = new IndexColumnListProcessor(); $cols = $processor->process($this->removeParenthesisFromStart($trim)); $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim, 'sub_tree' => $cols); $prevCategory = $currCategory; $currCategory = "INDEX_COL_LIST"; continue 3; } # index name $expr[] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim); continue 3; case 'KEY': case 'UNIQUE': case 'INDEX': if ($upper[0] === '(' && substr($upper, -1) === ')') { $processor = new IndexColumnListProcessor(); $cols = $processor->process($this->removeParenthesisFromStart($trim)); $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim, 'sub_tree' => $cols); $prevCategory = $currCategory; $currCategory = "INDEX_COL_LIST"; continue 3; } # index name $expr[] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim); continue 3; case 'CONSTRAINT': # constraint name $last = array_pop($expr); $last['base_expr'] = $base_expr; $last['sub_tree'] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim); $expr[] = $last; continue 3; case 'INDEX_PARSER': # index parser name $last = array_pop($expr); $last['sub_tree'][] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim); $expr[] = array('expr_type' => ExpressionType::INDEX_PARSER, 'base_expr' => $base_expr, 'sub_tree' => $last['sub_tree']); $base_expr = $last['base_expr'] . $base_expr; $currCategory = 'INDEX_COL_LIST'; continue 3; case 'INDEX_SIZE': # index key block size numeric constant $last = array_pop($expr); $last['sub_tree'][] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim); $expr[] = array('expr_type' => ExpressionType::INDEX_SIZE, 'base_expr' => $base_expr, 'sub_tree' => $last['sub_tree']); $base_expr = $last['base_expr'] . $base_expr; $currCategory = 'INDEX_COL_LIST'; continue 3; case 'CHECK': if ($upper[0] === '(' && substr($upper, -1) === ')') { $processor = new ExpressionListProcessor(); $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($trim)); $parsed = $processor->process($unparsed); $expr[] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim, 'sub_tree' => $parsed); } # else? break; case '': # if the currCategory is empty, we have an unknown token, # which is a column reference $expr[] = array('expr_type' => ExpressionType::COLREF, 'base_expr' => $trim, 'no_quotes' => $this->revokeQuotation($trim)); $currCategory = 'COLUMN_NAME'; continue 3; case 'COLUMN_NAME': # the column-definition # it stops on a comma or on a parenthesis $processor = new ColumnDefinitionProcessor(); $parsed = $processor->process(array_slice($tokens, $k, null, true), $expr); $skip = $parsed['till'] - $k; unset($parsed['till']); $expr[] = $parsed; $currCategory = ''; break; default: # ? break; } break; } $prevCategory = $currCategory; $currCategory = ''; } $type = $this->correctExpressionType($expr); $result['create-def'][] = array('expr_type' => $type, 'base_expr' => trim($base_expr), 'sub_tree' => $expr); return $result; }
protected function processExpressionList($tokens) { $processor = new ExpressionListProcessor(); return $processor->process($tokens); }
protected function processExpressionList($unparsed) { $processor = new ExpressionListProcessor($this->options); return $processor->process($unparsed); }