diff --git a/mysql_fdw.c b/mysql_fdw.c index ed77c99..35afb82 100644 --- a/mysql_fdw.c +++ b/mysql_fdw.c @@ -623,69 +623,72 @@ mysqlGetForeignRelSize(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntablei server = GetForeignServer(table->serverid); user = GetUserMapping(userid, server->serverid); - /* Fetch the options */ - options = mysql_get_options(foreigntableid); - - /* Fetch options */ options = mysql_get_options(foreigntableid); - /* Connect to the server */ - conn = mysql_get_connection(server, user, options); - - _mysql_query(conn, "SET sql_mode='ANSI_QUOTES'"); - - /* Build the query */ - initStringInfo(&sql); - - pull_varattnos((Node *) baserel->reltargetlist, baserel->relid, &attrs_used); - - appendStringInfo(&sql, "EXPLAIN "); - mysql_deparse_select(&sql, root, baserel, attrs_used, options->svr_table, &retrieved_attrs); - - /* - * TODO: MySQL seems to have some pretty unhelpful EXPLAIN output, which only - * gives a row estimate for each relation in the statement. We'll use the - * sum of the rows as our cost estimate - it's not great (in fact, in some - * cases it sucks), but it's all we've got for now. - */ - if (_mysql_query(conn, sql.data) != 0) - { - switch(_mysql_errno(conn)) - { - case CR_NO_ERROR: - break; - - case CR_OUT_OF_MEMORY: - case CR_SERVER_GONE_ERROR: - case CR_SERVER_LOST: - case CR_UNKNOWN_ERROR: - { - char *err = pstrdup(_mysql_error(conn)); - mysql_rel_connection(conn); - ereport(ERROR, - (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), - errmsg("failed to execute the MySQL query: \n%s", err))); - } - break; - case CR_COMMANDS_OUT_OF_SYNC: - default: - { - char *err = pstrdup(_mysql_error(conn)); - ereport(ERROR, - (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), - errmsg("failed to execute the MySQL query: \n%s", err))); - } - } - } - result = _mysql_store_result(conn); - if (result) - { - while ((row = _mysql_fetch_row(result))) - rows += row[8] ? atof(row[8]) : 2; - - _mysql_free_result(result); - } + if (options->svr_cost == 0) + { + /* Connect to the server */ + conn = mysql_get_connection(server, user, options); + + _mysql_query(conn, "SET sql_mode='ANSI_QUOTES'"); + + /* Build the query */ + initStringInfo(&sql); + + pull_varattnos((Node *) baserel->reltargetlist, baserel->relid, &attrs_used); + + appendStringInfo(&sql, "EXPLAIN "); + mysql_deparse_select(&sql, root, baserel, attrs_used, options->svr_table, &retrieved_attrs); + + /* + * TODO: MySQL seems to have some pretty unhelpful EXPLAIN output, which only + * gives a row estimate for each relation in the statement. We'll use the + * sum of the rows as our cost estimate - it's not great (in fact, in some + * cases it sucks), but it's all we've got for now. + */ + if (_mysql_query(conn, sql.data) != 0) + { + switch(_mysql_errno(conn)) + { + case CR_NO_ERROR: + break; + + case CR_OUT_OF_MEMORY: + case CR_SERVER_GONE_ERROR: + case CR_SERVER_LOST: + case CR_UNKNOWN_ERROR: + { + char *err = pstrdup(_mysql_error(conn)); + mysql_rel_connection(conn); + ereport(ERROR, + (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), + errmsg("failed to execute the MySQL query: \n%s", err))); + } + break; + case CR_COMMANDS_OUT_OF_SYNC: + default: + { + char *err = pstrdup(_mysql_error(conn)); + ereport(ERROR, + (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), + errmsg("failed to execute the MySQL query: \n%s", err))); + } + } + } + result = _mysql_store_result(conn); + if (result) + { + while ((row = _mysql_fetch_row(result))) + rows += row[8] ? atof(row[8]) : 2; + + _mysql_free_result(result); + } + } + else + { + rows = options->svr_cost; + } baserel->rows = rows; baserel->tuples = rows; } diff --git a/mysql_fdw.h b/mysql_fdw.h index 807526f..db3409b 100644 --- a/mysql_fdw.h +++ b/mysql_fdw.h @@ -52,6 +52,7 @@ typedef struct mysql_opt char *svr_password; /* MySQL password */ char *svr_database; /* MySQL database name */ char *svr_table; /* MySQL table name */ + int svr_cost; /* MySQL table cost */ } mysql_opt; /* diff --git a/option.c b/option.c index 7da0aac..d4cb568 100644 --- a/option.c +++ b/option.c @@ -66,6 +66,7 @@ static struct MySQLFdwOption valid_options[] = { "password", UserMappingRelationId }, { "dbname", ForeignTableRelationId }, { "table_name", ForeignTableRelationId }, + { "cost", ForeignTableRelationId }, /* Sentinel */ { NULL, InvalidOid } @@ -192,6 +193,9 @@ mysql_get_options(Oid foreigntableid) if (strcmp(def->defname, "table_name") == 0) opt->svr_table = defGetString(def); + + if (strcmp(def->defname, "cost") == 0) + opt->svr_cost = atoi(defGetString(def)); } /* Default values, if required */ if (!opt->svr_address)