Skip to content

v2.1.14 #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Aug 14, 2024
Merged

v2.1.14 #155

merged 12 commits into from
Aug 14, 2024

Conversation

aristath
Copy link
Member

No description provided.

jeroenpf and others added 12 commits July 30, 2024 11:27
This PR addresses an issue where the output of `show create table` is
incorrect when the table has a `NULL` column without a default value.

Here is an example:

```sql

-- Original MySQL query

CREATE TABLE `wp_usermeta` (
	`umeta_id` bigint(20) unsigned NOT NULL auto_increment,
	`user_id` bigint(20) unsigned NOT NULL default '0',
	`meta_key` varchar(255) default NULL,
	`meta_value` longtext,
	PRIMARY KEY  (`umeta_id`),
	KEY `user_id` (`user_id`),
	KEY `meta_key` (`meta_key`(191))
)

-- Output by `SHOW CREATE TABLE` via SQLite plugin

CREATE TABLE `wp_usermeta` (
	`umeta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
	`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
	`meta_key` varchar(255) DEFAULT NULL,
	`meta_value` longtext DEFAULT , -- Default value missing
	PRIMARY KEY (`umeta_id`),
	KEY `meta_key` (`meta_key`),
	KEY `user_id` (`user_id`)
);

-- After this fix

CREATE TABLE `wp_usermeta` (
	`umeta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
	`user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
	`meta_key` varchar(255) DEFAULT NULL,
	`meta_value` longtext,
	PRIMARY KEY (`umeta_id`),
	KEY `meta_key` (`meta_key`),
	KEY `user_id` (`user_id`)
);
```
This PR addresses an issue where the ALTER TABLE CHANGE with skipped
COLUMNS keyword was ignored.

We supporter query

```sql
-- Processed correctly
ALTER TABLE _tmp_table CHANGE COLUMN name firstname varchar(50) NOT NULL default 'mark';

-- Was ignored
ALTER TABLE _tmp_table CHANGE name firstname varchar(50) NOT NULL default 'mark';
```
This PR fixes the issue by adding support for optional COLUMN in the
ALTER TABLE CHANGE query
This PR adds support for the following valid ALTER TABLE syntax:
```sql
ALTER TABLE <table-name> ADD <column-name> <data-type>;
```
and
```sql
ALTER TABLE <table-name> DROP <column-name>;
```

Prior to this PR, these queries do not work and result in error
conditions.

For reference, here is the documented SQLite syntax for ALTER TABLE
queries:
https://www.sqlite.org/syntax/alter-table-stmt.html

It shows that the COLUMN keyword is optional, and I've successfully
tested syntax without the COLUMN keyword in both MySQL and SQLite.

Reported by @JanJakes
Supporting `WAL` mode is good, however if we add support for that, we
should also add supoport for other journaling types as well.
This PR adds a `SQLITE_JOURNAL_MODE` constant, and if it has one of the
valid & supported values, then we make the query to set the
`journal_mode` in the DB.

Props @soulteary 👍
…from a CREATE TABLE IF NOT EXISTS (#134)

Before this the unit test failed.

cc @JanJakes

---------

Co-authored-by: Ari Stathopoulos <[email protected]>
Co-authored-by: Brandon Payton <[email protected]>
Add handling for adding/modifying columns with FIRST/AFTER, such as:

```sql
ALTER TABLE _tmp_table ADD COLUMN new_first_column VARCHAR(255) NOT NULL DEFAULT '' FIRST;
ALTER TABLE _tmp_table ADD COLUMN new_column VARCHAR(255) NOT NULL DEFAULT '' AFTER id;
ALTER TABLE _tmp_table CHANGE id id int(11) NOT NULL FIRST;
ALTER TABLE _tmp_table CHANGE id id int(11) NOT NULL AFTER name;
```

SQLite doesn't support FIRST/AFTER, so this implementation simply
ignores these. Previously, for ADD COLUMN statements, it ended up with
`SQLSTATE[HY000]: General error: 1 near "FIRST": syntax error.` and
`SQLSTATE[HY000]: General error: 1 near "AFTER": syntax error.`; for
CHANGE statements, this was already ignored and I only added a test.
The `ON UPDATE CURRENT_TIMESTAMP` is a special MySQL-specific construct
that can be used in column definitions. There is no such functionality
in SQLite. This pull request implements the `ON UPDATE
CURRENT_TIMESTAMP` functionality for both `CREATE` and `ALTER` table
commands using **triggers**.

With queries such as:
```sql
CREATE TABLE _tmp_table (
	id int(11) NOT NULL,
	created_at timestamp NULL ON UPDATE CURRENT_TIMESTAMP
);

ALTER TABLE _tmp_table ADD COLUMN updated_at timestamp NULL ON UPDATE CURRENT_TIMESTAMP;
```

The following triggers will be added:
```sql
-- created_at
CREATE TRIGGER "___tmp_table_created_at_on_update__"
AFTER UPDATE ON "_tmp_table"
FOR EACH ROW
BEGIN
  UPDATE "_tmp_table" SET "created_at" = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;

-- updated_at
CREATE TRIGGER "___tmp_table_updated_at_on_update__"
AFTER UPDATE ON "_tmp_table"
FOR EACH ROW
BEGIN
  UPDATE "_tmp_table" SET "updated_at" = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;
```

When the `ON UPDATE` is dropped using a query such as the following:
```sql
ALTER TABLE _tmp_table
CHANGE created_at created_at timestamp NULL,
CHANGE COLUMN updated_at updated_at timestamp NULL
```

The triggers are dropped as well. To ensure this always works, the
trigger is always dropped when a column is being altered. Then, if `ON
UPDATE` is present, it will be recreated; otherwise, it will remain
dropped.

Resolves
#148.
While SQLite does support `CURRENT_TIMESTAMP` function calls natively,
it doesn't support calling the function with parentheses in the form of
`CURRENT_TIMESTAMP()`.

This pull request removes the parentheses after `CURRENT_TIMESTAMP`
keyword for all types of queries.

The following types of queries will now work:

```sql
SELECT
    current_timestamp AS t1,
    CURRENT_TIMESTAMP AS t2,
    current_timestamp() AS t3,
    CURRENT_TIMESTAMP() AS t4;

INSERT INTO _dates (option_name, option_value) VALUES ('first', current_timestamp());

UPDATE _dates SET option_value = CURRENT_TIMESTAMP();

DELETE FROM _dates WHERE option_value = CURRENT_TIMESTAMP();
```

Closes
#129.

---------

Co-authored-by: Bero <[email protected]>
This PR modifies the SQLite database integration plugin ensuring LIKE
BINARY queries are supported.

The translator has been updated to utilize the `GLOB` SQLite function to
support the `LIKE BINARY` clause in Sqlite, ensuring it respects case
sensitivity.

### Example query
**MySQL**
```sql
SELECT * FROM _tmp_table WHERE name LIKE BINARY 'f%'
```

**SQLite**
```sql
SELECT * FROM _tmp_table WHERE name GLOB 'f*'
```

---------

Co-authored-by: Ari Stathopoulos <[email protected]>
Co-authored-by: Jeroen P <[email protected]>
Co-authored-by: Rostislav Wolný <[email protected]>
@aristath aristath merged commit 3c5455a into main Aug 14, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants