Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

ibase_driver returning whitespace in table/column names #3142

Closed
wants to merge 2 commits into from

3 participants

@hArpanet

Currently all Table and Field names are returned padded with whitespace up to string(124).

@narfbg
Owner

Wouldn't this change the resulting "column" names? It'd have to use either aliasing or PHP trimming (rtrim() being optimal).

@hArpanet

Well, the resulting 'column' (singular) name would be changed (to trim("RDB$RELATION_NAME") from "RD$RELATION_NAME" etc.) - or, more precisely, it's actually changed to just trim.

But, the associated list_tables() or list_columns() methods in DB_driver.php are looking for result columns named table_name or TABLE_NAME which are not returned by ibase. (If a specific $key is provided, then it will look only in that 'column', which would be affected by this change, but I can't find where $key is defined anyway.)

In ibase's case, the actual results are pulled using the 'no other choice but to get the first element' clause.

@narfbg
Owner

I see ...

I guess it's ok then. Could you just change that lower-case trim() to TRIM()? We use upper-case for SQL code.

@hArpanet

As DB_driver is looking for a column named 'table_name' shall I go ahead and alias the result to that as well? ie. TRIM($RDB$RELATION_NAME) AS TABLE_NAME

@narfbg
Owner

As long as you've tested it and know that it works - sure.

@narfbg
Owner

Well?

@timw4mail

I seem to remember this being an issue in some other code I looked at.

Here: https://github.com/timw4mail/Query/blob/master/drivers/firebird/firebird_sql.php#L96

So, yes, this looks like a good fix to me.

@hArpanet

Sorry guys, this is still pending testing. Definitely not forgotten about. I want to run a few tests against this first and clarify firebird server and client versions before I sign this off.

@hArpanet

Here's the DB/Table definition

CREATE DATABASE '10.11.12.13/gds_db:/databases/ibtest.fdb'
USER 'SYSDBA'
PASSWORD 'masterkey'
PAGE_SIZE = 4096
DEFAULT CHARACTER SET NONE


---------- STATEMENT ----------

CREATE GENERATOR TABLEA_FLD1_GEN;


CREATE TABLE TABLEA (
  TABLEA_ID INTEGER NOT NULL,
  TABLEA_VCHAR VARCHAR(255) CHARACTER SET NONE COLLATE NONE,
  TABLEA_DT TIMESTAMP DEFAULT CURRENT_TIMESTAMP  NOT NULL);


ALTER TABLE TABLEA ADD PRIMARY KEY (TABLEA_ID);


SET TERM ^ ;

CREATE TRIGGER BI_TABLEA_TABLEA_ID FOR TABLEA
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.TABLEA_ID IS NULL) THEN
      NEW.TABLEA_ID = GEN_ID(TABLEA_FLD1_GEN, 1);
END^

SET TERM ; ^

INSERT INTO TABLEA ("TABLEA_VCHAR") VALUE ('CI TEST');
INSERT INTO TABLEA ("TABLEA_VCHAR") VALUE ('CI TEST 2');

SELECT * FROM TABLEA

TABLEA_ID   TABLEA_VCHAR    TABLEA_DT
1           CI TEST         21/08/2014 09:22:10
2           CI TEST 2       21/08/2014 09:22:36

---------------------------------

---------- STATEMENT ----------

CREATE GENERATOR D3M0N1C_TBL_C0L_T3ST_1_GEN;


CREATE TABLE D3M0N1C_TBL (
  C0L_T3ST_1 INTEGER NOT NULL,
  "WITH!PLING" DECIMAL(12, 2) DEFAULT 42.24,
  "BL0B[TEST]" BLOB);


ALTER TABLE D3M0N1C_TBL ADD PRIMARY KEY (C0L_T3ST_1);


SET TERM ^ ;

CREATE TRIGGER BI_D3M0N1C_TBL_C0L_T3ST_1 FOR D3M0N1C_TBL
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.C0L_T3ST_1 IS NULL) THEN
      NEW.C0L_T3ST_1 = GEN_ID(D3M0N1C_TBL_C0L_T3ST_1_GEN, 1);
END^

SET TERM ; ^

INSERT INTO D3M0N1C_TBL ("WITH!PLING", "BL0B[TEST]") VALUES (1.23, 'BLOBBY RULES');
INSERT INTO D3M0N1C_TBL ("WITH!PLING", "BL0B[TEST]") VALUES (NULL, 'BLOBBY BLOBBY BLOBBY');
COMMIT;

SELECT * FROM D3M0N1C_TBL

C0L_T3ST_1  WITH!PLING
1           1.23
2           NULL

Here's the test code I've run (once with existing CI code, once with TRIMmed code)


    public function ibase_test() {
        foreach (array('benchmarks','config','controller_info','get','http_headers','memory_usage','post','uri_string','query_toggle_count') as $p)
            $this->output->set_profiler_sections(array($p=>false));

        $config = array('hostname' => 'localhost',
                        'username' => 'SYSDBA',
                        'password' => 'masterkey',
                        'database' => '/databases/ibtest.fdb',
                        'dbdriver' => 'ibase');

        $this->load->database($config);

        echo '<pre>';

        $test_result = $this->db->list_tables();
        foreach($test_result as $k=>$v) {
            echo "==============================================\n";

            echo "Length: [".strlen($v)."] Table: [{$v}]\n\n";
            $this->debug($test_result, 'TEST 1 TABLES', true);

            # table fields
            $test_fields = $this->db->list_fields($v);
            foreach ($test_fields as $k1=>$v1) {
                echo "   Length: [".strlen($v1)."] Column: [{$v1}]\n";
                $this->debug($test_fields, 'TEST 1 FIELDS', true);
            }

            # table rows
            echo "\n";
            $data = $this->db->query("SELECT * FROM {$v}");
            foreach ($data->result() as $row)
                echo print_r($row, true);

        }

        echo '</pre>';
    }

Here's the results

=== TEST 1 WITHOUT TRIM APPLIED ===

==============================================
Length: [124] Table: [TABLEA                                                                                                                      ]

   Length: [124] Column: [TABLEA_ID                                                                                                                   ]
   Length: [124] Column: [TABLEA_VCHAR                                                                                                                ]
   Length: [124] Column: [TABLEA_DT                                                                                                                   ]
stdClass Object
(
    [TABLEA_ID] => 1
    [TABLEA_VCHAR] => CI TEST 2
    [TABLEA_DT] => 2014-08-21 09:22:36
)
stdClass Object
(
    [TABLEA_ID] => 2
    [TABLEA_VCHAR] => CI TEST
    [TABLEA_DT] => 2014-08-21 09:22:10
)
==============================================
Length: [124] Table: [D3M0N1C_TBL                                                                                                                 ]

   Length: [124] Column: [C0L_T3ST_1                                                                                                                  ]
   Length: [124] Column: [WITH!PLING                                                                                                                  ]
   Length: [124] Column: [BL0B[TEST]                                                                                                                  ]

stdClass Object
(
    [C0L_T3ST_1] => 1
    [WITH!PLING] => 1.23
    [BL0B[TEST]] => BLOBBY RULES
)
stdClass Object
(
    [C0L_T3ST_1] => 2
    [WITH!PLING] => 
    [BL0B[TEST]] => BLOBBY BLOBBY BLOBBY
)
DATABASE:  /data/databases/ibtest.fdb (Test:$db)   QUERIES: 5 (0.0036 seconds)  (Hide)

0.0015    SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE 'RDB$%' AND "RDB$RELATION_NAME" NOT LIKE 'MON$%' 
0.0007    SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = 'TABLEA                                                                                                                      ' 
0.0006    SELECT * FROM TABLEA                                                                                                                       |<=ENDS HERE
0.0002    SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = 'D3M0N1C_TBL                                                                                                                 ' 
0.0005    SELECT * FROM D3M0N1C_TBL                                                                                        |<=ENDS HERE 
=== TEST 2 WITH TRIM APPLIED ===

==============================================
Length: [6] Table: [TABLEA]

   Length: [9] Column: [TABLEA_ID]
   Length: [12] Column: [TABLEA_VCHAR]
   Length: [9] Column: [TABLEA_DT]

stdClass Object
(
    [TABLEA_ID] => 1
    [TABLEA_VCHAR] => CI TEST 2
    [TABLEA_DT] => 2014-08-21 09:22:36
)
stdClass Object
(
    [TABLEA_ID] => 2
    [TABLEA_VCHAR] => CI TEST
    [TABLEA_DT] => 2014-08-21 09:22:10
)
==============================================
Length: [11] Table: [D3M0N1C_TBL]

   Length: [10] Column: [C0L_T3ST_1]
   Length: [10] Column: [WITH!PLING]
   Length: [10] Column: [BL0B[TEST]]

stdClass Object
(
    [C0L_T3ST_1] => 1
    [WITH!PLING] => 1.23
    [BL0B[TEST]] => BLOBBY RULES
)
stdClass Object
(
    [C0L_T3ST_1] => 2
    [WITH!PLING] => 
    [BL0B[TEST]] => BLOBBY BLOBBY BLOBBY
)
DATABASE:  /data/databases/ibtest.fdb (Test:$db)   QUERIES: 5 (0.0096 seconds)  (Hide)

0.0061    SELECT TRIM("RDB$RELATION_NAME") FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE 'RDB$%' AND "RDB$RELATION_NAME" NOT LIKE 'MON$%' 
0.0007    SELECT TRIM("RDB$FIELD_NAME") FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = 'TABLEA' 
0.0020    SELECT * FROM TABLEA|<=ENDS HERE
0.0002    SELECT TRIM("RDB$FIELD_NAME") FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = 'D3M0N1C_TBL' 
0.0005    SELECT * FROM D3M0N1C_TBL|<=ENDS HERE
Dave Harper ibase_driver returning whitespace in table/column names
Currently all Table and Field names are returned padded with whitespace
up to string(124).
f44dcb4
@hArpanet

new pull request created with upper case TRIM. see #3195

@hArpanet hArpanet closed this
@hArpanet

oops, just for future reference if relevant, from php_info...

interbase

Firebird/InterBase Support: dynamic
Compile-time Client Library Version: Firebird API version 21
Run-time Client Library Version: LI-V6.3.3.18185 Firebird 2.1

@narfbg
Owner

The new PR isn't any different from this one ... you had to test aliasing and do that.

@hArpanet

OK, forgot I mentioned aliasing the table name as well. Having looked at the other [name]_driver.php files (sqlite, sqlsrv, mysqli) they aren't bothering to alias their results to TABLE_NAME (or COLUMN_NAME in the case of listing fields).

For consistency, I guess we shouldn't make ibase_driver.php do it either (although there is a negligible performance overhead of not aliasing it). Unless you're of the opinion that now is as good a time as any to put the alias in place?

@narfbg
Owner

You asked if you should do the alias and I told you that you can do that as long as you've tested it ...

It's not a necessity, just wondering why you've wasted your time with other tests and produced the same exact patch as a result, only in another PR. And of course, if you'd be aliasing it - what better time for it than now?

@hArpanet

okie doke, I'll put the alias in there too and resubmit.

(This isn't the same PR as I changed the 'trim' to 'TRIM' as requested.)

@narfbg
Owner

Don't resubmit, just commit & push to the same branch.

@hArpanet

Alias names added.

No discernible performance difference (on a non-closed server using the test code shown earlier)...

10,000 calls with alias
run 1: 14.5784
run 2: 14.1829
run 3: 14.6936
run 4: 14.0495
run 5: 14.5446

10,000 calls without alias
run 1: 14.4771
run 2: 14.6140
run 3: 14.2767
run 4: 14.6951
run 5: 14.3482

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 11, 2014
  1. @hArpanet
Commits on Aug 21, 2014
  1. ibase_driver returning whitespace in table/column names

    Dave Harper authored
    Currently all Table and Field names are returned padded with whitespace
    up to string(124).
This page is out of date. Refresh to see the latest.
Showing with 3 additions and 3 deletions.
  1. +3 −3 system/database/drivers/ibase/ibase_driver.php
View
6 system/database/drivers/ibase/ibase_driver.php
@@ -219,11 +219,11 @@ public function insert_id($generator_name, $inc_by = 0)
*/
protected function _list_tables($prefix_limit = FALSE)
{
- $sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
+ $sql = 'SELECT TRIM("RDB$RELATION_NAME") FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
if ($prefix_limit !== FALSE && $this->dbprefix !== '')
{
- return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
+ return $sql.' AND TRIM("RDB$RELATION_NAME") LIKE \''.$this->escape_like_str($this->dbprefix)."%' "
.sprintf($this->_like_escape_str, $this->_like_escape_chr);
}
@@ -242,7 +242,7 @@ protected function _list_tables($prefix_limit = FALSE)
*/
protected function _list_columns($table = '')
{
- return 'SELECT "RDB$FIELD_NAME" FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table);
+ return 'SELECT TRIM("RDB$FIELD_NAME") FROM "RDB$RELATION_FIELDS" WHERE "RDB$RELATION_NAME" = '.$this->escape($table);
}
// --------------------------------------------------------------------
Something went wrong with that request. Please try again.