Skip to content

Commit

Permalink
Merge pull request #1023 from sjinks/issue-1011
Browse files Browse the repository at this point in the history
[PHQL] Add placeholders support to LIMIT
  • Loading branch information
Phalcon committed Aug 8, 2013
2 parents cf42b58 + 4f259f7 commit db6bd12
Show file tree
Hide file tree
Showing 15 changed files with 2,470 additions and 4,921 deletions.
7 changes: 7 additions & 0 deletions ext/db/adapter/pdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,15 @@ PHP_METHOD(Phalcon_Db_Adapter_Pdo, executePrepared){
Z_UNSET_ISREF_P(cast_value);

} else {
PHALCON_INIT_NVAR(type);
ZVAL_LONG(type, 2 /* BIND_PARAM_STR */);
Z_SET_ISREF_P(value);
phalcon_call_method_p3_noret(statement, "bindparam", parameter, value, type);
Z_UNSET_ISREF_P(value);
/*
PHALCON_THROW_EXCEPTION_STR(phalcon_db_exception_ce, "Invalid bind type parameter");
return;
*/
}
} else {
Z_SET_ISREF_P(value);
Expand Down
41 changes: 20 additions & 21 deletions ext/db/dialect.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,9 @@ PHP_METHOD(Phalcon_Db_Dialect, select){
zval *group_clause, *having_conditions, *having_expression;
zval *order_fields, *order_items, *order_item = NULL;
zval *order_expression = NULL, *order_sql_item = NULL, *sql_order_type = NULL;
zval *order_sql_item_type = NULL, *order_sql, *limit_value;
zval *number, *offset;
zval *order_sql_item_type = NULL, *order_sql, *tmp1 = NULL, *tmp2 = NULL;
zval **limit_value;
zval **number, **offset;
HashTable *ah0, *ah1, *ah2, *ah3, *ah4, *ah5;
HashPosition hp0, hp1, hp2, hp3, hp4, hp5;
zval **hd;
Expand Down Expand Up @@ -910,27 +911,25 @@ PHP_METHOD(Phalcon_Db_Dialect, select){
/**
* Check for a LIMIT condition
*/
if (phalcon_array_isset_string(definition, SS("limit"))) {

PHALCON_OBS_VAR(limit_value);
phalcon_array_fetch_string(&limit_value, definition, SL("limit"), PH_NOISY);
if (Z_TYPE_P(limit_value) == IS_ARRAY) {

PHALCON_OBS_VAR(number);
phalcon_array_fetch_string(&number, limit_value, SL("number"), PH_NOISY);

/**
* Check for a OFFSET condition
*/
if (phalcon_array_isset_string(limit_value, SS("offset"))) {
PHALCON_OBS_VAR(offset);
phalcon_array_fetch_string(&offset, limit_value, SL("offset"), PH_NOISY);
PHALCON_SCONCAT_SVSV(sql, " LIMIT ", number, " OFFSET ", offset);
} else {
PHALCON_SCONCAT_SV(sql, " LIMIT ", number);
if (phalcon_array_isset_string_fetch(&limit_value, definition, SS("limit"))) {
if (likely(Z_TYPE_PP(limit_value) == IS_ARRAY)) {
if (likely(phalcon_array_isset_string_fetch(&number, *limit_value, SS("number")))) {
PHALCON_OBS_NVAR(tmp1);
phalcon_array_fetch_string(&tmp1, *number, SL("value"), PH_NOISY);

/**
* Check for a OFFSET condition
*/
if (phalcon_array_isset_string_fetch(&offset, *limit_value, SS("offset"))) {
PHALCON_OBS_NVAR(tmp2);
phalcon_array_fetch_string(&tmp2, *offset, SL("value"), PH_NOISY);
PHALCON_SCONCAT_SVSV(sql, " LIMIT ", tmp1, " OFFSET ", tmp2);
} else {
PHALCON_SCONCAT_SV(sql, " LIMIT ", tmp1);
}
}
} else {
PHALCON_SCONCAT_SV(sql, " LIMIT ", limit_value);
PHALCON_SCONCAT_SV(sql, " LIMIT ", *limit_value);
}
}

Expand Down
63 changes: 26 additions & 37 deletions ext/db/dialect/oracle.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,8 +851,8 @@ PHP_METHOD(Phalcon_Db_Dialect_Oracle, select){
zval *group_clause, *having_conditions, *having_expression;
zval *order_fields, *order_items, *order_item = NULL;
zval *order_expression = NULL, *order_sql_item = NULL, *sql_order_type = NULL;
zval *order_sql_item_type = NULL, *order_sql, *limit_value;
zval *number, *offset;
zval *order_sql_item_type = NULL, *order_sql, **limit_value;
zval **number, **offset, *tmp1 = NULL, *tmp2 = NULL;
zval *one, *ini_range, *end_range, *sql_limit;
HashTable *ah0, *ah1, *ah2, *ah3, *ah4, *ah5;
HashPosition hp0, hp1, hp2, hp3, hp4, hp5;
Expand Down Expand Up @@ -1183,50 +1183,39 @@ PHP_METHOD(Phalcon_Db_Dialect_Oracle, select){
* Unfortunately because we use the column wildcard "*",
* this puts an extra column into the query result set.
*/
if (phalcon_array_isset_string(definition, SS("limit"))) {
if (phalcon_array_isset_string_fetch(&limit_value, definition, SS("limit"))) {
if (likely(Z_TYPE_PP(limit_value) == IS_ARRAY)) {
if (likely(phalcon_array_isset_string_fetch(&number, *limit_value, SS("number")))) {
PHALCON_OBS_NVAR(tmp1);
phalcon_array_fetch_string(&tmp1, *number, SL("value"), PH_NOISY);

if (phalcon_array_isset_string_fetch(&offset, *limit_value, SS("offset"))) {
PHALCON_OBS_NVAR(tmp2);
phalcon_array_fetch_string(&tmp2, *offset, SL("value"), PH_NOISY);
} else {
PHALCON_INIT_NVAR(tmp2);
ZVAL_LONG(tmp2, 0);
}

PHALCON_OBS_VAR(limit_value);
phalcon_array_fetch_string(&limit_value, definition, SL("limit"), PH_NOISY);
PHALCON_INIT_VAR(one);
ZVAL_LONG(one, 1);

if (Z_TYPE_P(limit_value) == IS_ARRAY) {
PHALCON_INIT_VAR(ini_range);
phalcon_add_function(ini_range, tmp2, one TSRMLS_CC);

PHALCON_OBS_VAR(number);
phalcon_array_fetch_string(&number, limit_value, SL("number"), PH_NOISY);
PHALCON_INIT_VAR(end_range);
phalcon_add_function(end_range, tmp2, tmp1 TSRMLS_CC);

if (phalcon_array_isset_string(limit_value, SS("offset"))) {
PHALCON_OBS_VAR(offset);
phalcon_array_fetch_string(&offset, limit_value, SL("offset"), PH_NOISY);
} else {
PHALCON_INIT_VAR(offset);
ZVAL_LONG(offset, 0);
PHALCON_INIT_VAR(sql_limit);
PHALCON_SCONCAT_SVSVSV(sql_limit,"SELECT Z2.* FROM (SELECT Z1.*, ROWNUM DB_ROWNUM FROM ( ", sql, " ) Z1 ) Z2 WHERE Z2.DB_ROWNUM BETWEEN ", ini_range , " AND ", end_range );
PHALCON_CPY_WRT(sql, sql_limit);
}

PHALCON_INIT_VAR(one);
ZVAL_LONG(one, 1);

PHALCON_INIT_VAR(ini_range);
phalcon_add_function(ini_range, offset, one TSRMLS_CC);

PHALCON_INIT_VAR(end_range);
phalcon_add_function(end_range, offset, number TSRMLS_CC);

PHALCON_INIT_VAR(sql_limit);
PHALCON_SCONCAT_SVSVSV(sql_limit,"SELECT Z2.* FROM (SELECT Z1.*, ROWNUM DB_ROWNUM FROM ( ", sql, " ) Z1 ) Z2 WHERE Z2.DB_ROWNUM BETWEEN ", ini_range , " AND ", end_range );
PHALCON_CPY_WRT(sql, sql_limit);

} else {

PHALCON_INIT_VAR(offset);
ZVAL_LONG(offset, 0);

PHALCON_INIT_VAR(one);
ZVAL_LONG(one, 1);

PHALCON_INIT_VAR(ini_range);
phalcon_add_function(ini_range, offset, one TSRMLS_CC);
ZVAL_LONG(ini_range, 1);

PHALCON_INIT_VAR(end_range);
phalcon_add_function(end_range, offset, limit_value TSRMLS_CC);
PHALCON_CPY_WRT_CTOR(end_range, *limit_value);

PHALCON_INIT_VAR(sql_limit);
PHALCON_SCONCAT_SVSVSV(sql_limit,"SELECT Z2.* FROM (SELECT Z1.*, ROWNUM DB_ROWNUM FROM ( ", sql, " ) Z1 ) Z2 WHERE Z2.DB_ROWNUM BETWEEN ", ini_range , " AND ", end_range );
Expand Down
10 changes: 7 additions & 3 deletions ext/mvc/model/manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -2828,17 +2828,21 @@ PHP_METHOD(Phalcon_Mvc_Model_Manager, createQuery){
*/
PHP_METHOD(Phalcon_Mvc_Model_Manager, executeQuery){

zval *phql, *placeholders = NULL, *dependency_injector;
zval *phql, *placeholders = NULL, *types = NULL, *dependency_injector;
zval *query;

PHALCON_MM_GROW();

phalcon_fetch_params(1, 1, 1, &phql, &placeholders);
phalcon_fetch_params(1, 1, 2, &phql, &placeholders, &types);

if (!placeholders) {
PHALCON_INIT_VAR(placeholders);
}

if (!types) {
PHALCON_INIT_VAR(types);
}

PHALCON_OBS_VAR(dependency_injector);
phalcon_read_property_this(&dependency_injector, this_ptr, SL("_dependencyInjector"), PH_NOISY_CC);
if (Z_TYPE_P(dependency_injector) != IS_OBJECT) {
Expand All @@ -2859,7 +2863,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Manager, executeQuery){
/**
* Execute the query
*/
phalcon_call_method_p1(return_value, query, "execute", placeholders);
phalcon_call_method_p2(return_value, query, "execute", placeholders, types);
RETURN_MM();
}

Expand Down
1 change: 1 addition & 0 deletions ext/mvc/model/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_phalcon_mvc_model_manager_executequery, 0, 0, 1)
ZEND_ARG_INFO(0, phql)
ZEND_ARG_INFO(0, placeholders)
ZEND_ARG_INFO(0, types)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_phalcon_mvc_model_manager_createbuilder, 0, 0, 0)
Expand Down
61 changes: 44 additions & 17 deletions ext/mvc/model/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,32 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _getGroupClause){
RETURN_CTOR(group_parts);
}

PHP_METHOD(Phalcon_Mvc_Model_Query, _getLimitClause) {
zval *limit_clause, *tmp = NULL;
zval **limit, **offset;

phalcon_fetch_params(0, 1, 0, &limit_clause);
assert(Z_TYPE_P(limit_clause) == IS_ARRAY);

array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(limit_clause)));

PHALCON_MM_GROW();

if (likely(phalcon_array_isset_string_fetch(&limit, limit_clause, SS("number")))) {
PHALCON_INIT_NVAR(tmp);
phalcon_call_method_p1(tmp, getThis(), "_getexpression", *limit);
phalcon_array_update_string(&return_value, SL("number"), &tmp, PH_COPY);
}

if (phalcon_array_isset_string_fetch(&offset, limit_clause, SS("offset"))) {
PHALCON_INIT_NVAR(tmp);
phalcon_call_method_p1(tmp, getThis(), "_getexpression", *offset);
phalcon_array_update_string(&return_value, SL("offset"), &tmp, PH_COPY);
}

PHALCON_MM_RESTORE();
}

/**
* Analyzes a SELECT intermediate code and produces an array to be executed later
*
Expand All @@ -2438,7 +2464,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareSelect){
zval *sql_column_group = NULL, *sql_column = NULL, *type = NULL, *sql_select;
zval *where, *where_expr, *group_by, *sql_group;
zval *having, *having_expr, *order, *sql_order;
zval *limit;
zval **limit, *sql_limit;
HashTable *ah0, *ah1, *ah2;
HashPosition hp0, hp1, hp2;
zval **hd;
Expand Down Expand Up @@ -2824,10 +2850,10 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareSelect){
/**
* Process LIMIT clause if any
*/
if (phalcon_array_isset_string(ast, SS("limit"))) {
PHALCON_OBS_VAR(limit);
phalcon_array_fetch_string(&limit, ast, SL("limit"), PH_NOISY);
phalcon_array_update_string(&sql_select, SL("limit"), &limit, PH_COPY | PH_SEPARATE);
if (phalcon_array_isset_string_fetch(&limit, ast, SS("limit"))) {
PHALCON_INIT_VAR(sql_limit);
phalcon_call_method_p1(sql_limit, this_ptr, "_getlimitclause", *limit);
phalcon_array_update_string(&sql_select, SL("limit"), &sql_limit, PH_COPY);
}

RETURN_CTOR(sql_select);
Expand Down Expand Up @@ -3005,7 +3031,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareUpdate){
zval *values, *update_values = NULL, *not_quoting = NULL, *update_value = NULL;
zval *column = NULL, *sql_column = NULL, *expr_column = NULL, *expr_value = NULL;
zval *type = NULL, *value = NULL, *sql_update, *where, *where_expr;
zval *limit;
zval **limit, *sql_limit;
HashTable *ah0, *ah1;
HashPosition hp0, hp1;
zval **hd;
Expand Down Expand Up @@ -3226,10 +3252,10 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareUpdate){
phalcon_array_update_string(&sql_update, SL("where"), &where_expr, PH_COPY | PH_SEPARATE);
}

if (phalcon_array_isset_string(ast, SS("limit"))) {
PHALCON_OBS_VAR(limit);
phalcon_array_fetch_string(&limit, ast, SL("limit"), PH_NOISY);
phalcon_array_update_string(&sql_update, SL("limit"), &limit, PH_COPY | PH_SEPARATE);
if (phalcon_array_isset_string_fetch(&limit, ast, SS("limit"))) {
PHALCON_INIT_VAR(sql_limit);
phalcon_call_method_p1(sql_limit, this_ptr, "_getlimitclause", *limit);
phalcon_array_update_string(&sql_update, SL("limit"), &sql_limit, PH_COPY);
}

RETURN_CTOR(sql_update);
Expand All @@ -3249,7 +3275,8 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareDelete){
zval *model_name = NULL, *ns_alias = NULL, *real_namespace = NULL;
zval *real_model_name = NULL, *model = NULL, *source = NULL, *schema = NULL;
zval *complete_source = NULL, *alias = NULL, *sql_delete, *not_quoting;
zval *where, *where_expr, *limit;
zval *where, *where_expr;
zval **limit, *sql_limit;
HashTable *ah0;
HashPosition hp0;
zval **hd;
Expand Down Expand Up @@ -3407,12 +3434,12 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareDelete){
phalcon_array_update_string(&sql_delete, SL("where"), &where_expr, PH_COPY | PH_SEPARATE);
}

if (phalcon_array_isset_string(ast, SS("limit"))) {
PHALCON_OBS_VAR(limit);
phalcon_array_fetch_string(&limit, ast, SL("limit"), PH_NOISY);
phalcon_array_update_string(&sql_delete, SL("limit"), &limit, PH_COPY | PH_SEPARATE);
if (phalcon_array_isset_string_fetch(&limit, ast, SS("limit"))) {
PHALCON_INIT_VAR(sql_limit);
phalcon_call_method_p1(sql_limit, this_ptr, "_getlimitclause", *limit);
phalcon_array_update_string(&sql_delete, SL("limit"), &sql_limit, PH_COPY);
}

RETURN_CTOR(sql_delete);
}

Expand Down Expand Up @@ -3443,7 +3470,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, parse){
*/
PHALCON_INIT_VAR(ast);
if (phql_parse_phql(ast, phql TSRMLS_CC) == FAILURE) {
return;
RETURN_MM();
}

PHALCON_INIT_VAR(ir_phql);
Expand Down
2 changes: 2 additions & 0 deletions ext/mvc/model/query.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query, _getMultiJoin);
PHP_METHOD(Phalcon_Mvc_Model_Query, _getJoins);
PHP_METHOD(Phalcon_Mvc_Model_Query, _getOrderClause);
PHP_METHOD(Phalcon_Mvc_Model_Query, _getGroupClause);
PHP_METHOD(Phalcon_Mvc_Model_Query, _getLimitClause);
PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareSelect);
PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareInsert);
PHP_METHOD(Phalcon_Mvc_Model_Query, _prepareUpdate);
Expand Down Expand Up @@ -126,6 +127,7 @@ PHALCON_INIT_FUNCS(phalcon_mvc_model_query_method_entry){
PHP_ME(Phalcon_Mvc_Model_Query, _getJoins, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _getOrderClause, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _getGroupClause, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _getLimitClause, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _prepareSelect, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _prepareInsert, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Mvc_Model_Query, _prepareUpdate, NULL, ZEND_ACC_PROTECTED)
Expand Down
2 changes: 1 addition & 1 deletion ext/mvc/model/query/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ int phql_parse_phql(zval *result, zval *phql TSRMLS_DC) {
ZVAL_NULL(result);

if (phql_internal_parse_phql(&result, Z_STRVAL_P(phql), Z_STRLEN_P(phql), &error_msg TSRMLS_CC) == FAILURE) {
PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, Z_STRVAL_P(error_msg));
PHALCON_THROW_EXCEPTION_STRW(phalcon_mvc_model_exception_ce, Z_STRVAL_P(error_msg));
return FAILURE;
}

Expand Down
2 changes: 1 addition & 1 deletion ext/mvc/model/query/lang.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ PHP_METHOD(Phalcon_Mvc_Model_Query_Lang, parsePHQL){
return;
}
if (phql_parse_phql(return_value, phql TSRMLS_CC) == FAILURE) {
return;
RETURN_MM();
}
RETURN_MM();
}
Expand Down
Loading

0 comments on commit db6bd12

Please sign in to comment.