SQL o TSQL Turing sono completi?


171

Questo è successo in ufficio oggi. Non ho intenzione di fare una cosa del genere, ma teoricamente potresti scrivere un compilatore in SQL? A prima vista mi sembra essere completo, anche se estremamente ingombrante per molte classi di problemi.

Se non è completo, cosa richiederebbe per diventarlo?

Nota: non ho alcun desiderio di fare qualcosa come scrivere un compilatore in SQL, so che sarebbe una cosa sciocca da fare, quindi se potessimo evitare quella discussione lo apprezzerei.

Risposte:


219

Si scopre che SQL può essere Turing Complete anche senza una vera estensione di "scripting" come PL / SQL o PSM (che sono progettati per essere veri linguaggi di programmazione, quindi è un po 'barare).

In questo set di diapositive Andrew Gierth dimostra che con CTE e Windowing SQL è Turing Complete, costruendo un sistema di tag ciclico , che si è rivelato essere Turing Complete. La funzionalità CTE è tuttavia la parte importante: consente di creare sottoespressioni denominate che possono fare riferimento a se stesse e risolvere in modo ricorsivo i problemi.

La cosa interessante da notare è che CTE non è stato realmente aggiunto per trasformare SQL in un linguaggio di programmazione - solo per trasformare un linguaggio di interrogazione dichiarativo in un linguaggio di interrogazione dichiarativo più potente. Un po 'come in C ++, i cui modelli si sono rivelati completi di Turing anche se non erano destinati a creare un linguaggio di meta-programmazione.

Oh, anche il set di Mandelbrot nell'esempio SQL è davvero impressionante :)


1
Anche Oracle SQL sta diventando completo, anche se in modo piuttosto malato: blog.schauderhaft.de/2009/06/18/…
Jens Schauder,

2
> Si scopre che SQL non dovrebbe dire: risulta che SQL: 1999? Detto questo perché i CTE sono stati aggiunti nella versione 99 e troppe persone associano sql standard a Mq 92.
Ernesto

1
@JensSchauder che può essere generalizzato a "Oracle $ technology is $ some_good_feature, sebbene in modo piuttosto malato"
Rob Grant

3
Sono passati 9 anni ma questo potrebbe essere interessante beta.observablehq.com/@pallada-92/sql-3d-engine
Loupax

33

Si dice che un determinato linguaggio di programmazione sia completo di Turing se si può dimostrare che è computazionalmente equivalente a una macchina di Turing.

TSQL è Turing Complete perché possiamo creare un interprete BrainFuck in TSQL.

Interprete BrainFuck in SQL - GitHub

Il codice fornito funziona in memoria e non modifica un database.

-- Brain Fuck interpreter in SQL

DECLARE @Code  VARCHAR(MAX) = ', [>,] < [.<]'
DECLARE @Input VARCHAR(MAX) = '!dlroW olleH';

-- Creates a "BrainFuck" DataBase.
-- CREATE DATABASE BrainFuck;

-- Creates the Source code table
DECLARE @CodeTable TABLE (
    [Id]      INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Command] CHAR(1) NOT NULL
);

-- Populate the source code into CodeTable
DECLARE @CodeLen INT = LEN(@Code);
DECLARE @CodePos INT = 0;
DECLARE @CodeChar CHAR(1);

WHILE @CodePos < @CodeLen
BEGIN
    SET @CodePos  = @CodePos + 1;
    SET @CodeChar = SUBSTRING(@Code, @CodePos, 1);
    IF @CodeChar IN ('+', '-', '>', '<', ',', '.', '[', ']')
        INSERT INTO @CodeTable ([Command]) VALUES (@CodeChar)
END

-- Creates the Input table
DECLARE @InputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Populate the input text into InputTable
DECLARE @InputLen INT = LEN(@Input);
DECLARE @InputPos INT = 0;

WHILE @InputPos < @InputLen
BEGIN
    SET @InputPos = @InputPos + 1;
    INSERT INTO @InputTable ([Char])
    VALUES (SUBSTRING(@Input, @InputPos, 1))
END

-- Creates the Output table
DECLARE @OutputTable TABLE (
    [Id]   INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Char] CHAR(1) NOT NULL
);

-- Creates the Buffer table
DECLARE @BufferTable TABLE (
    [Id]     INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    [Memory] INT DEFAULT 0  NOT NULL
);
INSERT INTO @BufferTable ([Memory])
VALUES (0);

-- Initialization of temporary variables 
DECLARE @CodeLength INT = (SELECT COUNT(*) FROM @CodeTable);
DECLARE @CodeIndex  INT = 0;
DECLARE @Pointer    INT = 1;
DECLARE @InputIndex INT = 0;
DECLARE @Command    CHAR(1);
DECLARE @Depth      INT;

-- Main calculation cycle
WHILE @CodeIndex < @CodeLength
BEGIN
    -- Read the next command.
    SET @CodeIndex = @CodeIndex + 1;
    SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);

    -- Increment the pointer.
    IF @Command = '>'
    BEGIN
        SET @Pointer = @Pointer + 1;
        IF (SELECT [Id] FROM @BufferTable WHERE [Id] = @Pointer) IS NULL
            INSERT INTO @BufferTable ([Memory]) VALUES (0);
    END

    -- Decrement the pointer.
    ELSE IF @Command = '<'
        SET @Pointer = @Pointer - 1;

    -- Increment the byte at the pointer.
    ELSE IF @Command = '+'
        UPDATE @BufferTable SET [Memory] = [Memory] + 1 WHERE [Id] = @Pointer;

    -- Decrement the byte at the pointer.
    ELSE IF @Command = '-'
        UPDATE @BufferTable SET [Memory] = [Memory] - 1 WHERE [Id] = @Pointer;

    -- Output the byte at the pointer.
    ELSE IF @Command = '.'
        INSERT INTO @OutputTable ([Char]) (SELECT CHAR([Memory]) FROM @BufferTable WHERE [Id] = @Pointer);

    -- Input a byte and store it in the byte at the pointer.
    ELSE IF @Command = ','
    BEGIN
        SET @InputIndex = @InputIndex + 1;
        UPDATE @BufferTable SET [Memory] = COALESCE((SELECT ASCII([Char]) FROM @InputTable WHERE [Id] = @InputIndex), 0) WHERE [Id] = @Pointer;
    END

    -- Jump forward past the matching ] if the byte at the pointer is zero.
    ELSE IF @Command = '[' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) = 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex + 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = '[' SET @Depth = @Depth + 1;
            ELSE IF @Command = ']' SET @Depth = @Depth - 1;
        END
    END

    -- Jump backwards to the matching [ unless the byte at the pointer is zero.
    ELSE IF @Command = ']' AND COALESCE((SELECT [Memory] FROM @BufferTable WHERE [Id] = @Pointer), 0) != 0
    BEGIN
        SET @Depth = 1;
        WHILE @Depth > 0
        BEGIN
            SET @CodeIndex = @CodeIndex - 1;
            SET @Command = (SELECT [Command] FROM @CodeTable WHERE [Id] = @CodeIndex);
            IF @Command = ']' SET @Depth = @Depth + 1;
            ELSE IF @Command = '[' SET @Depth = @Depth - 1;
        END
    END
END;

-- Collects and prints the output
DECLARE @Output VARCHAR(MAX);
SELECT @Output = COALESCE(@Output, '') + [Char]
FROM @OutputTable;

PRINT @Output;
Go

Questo è Transact SQL che è Turing completo, ANSI SQL che ho capito non è TC. Ma buon sforzo!
alimack

28

https://web.archive.org/web/20110807062050/http://channel9.msdn.com/forums/TechOff/431432-SQL-Turing-Completeness-question

È una discussione su questo argomento. Una citazione:

SQL in quanto tale (ovvero lo standard SQL92) non è completo. Tuttavia, molti dei linguaggi derivati ​​da SQL, come Oracle PL / SQL e SQL Server T-SQL e altri, sono in fase di completamento.

PL / SQL e T-SQL si qualificano certamente come linguaggi di programmazione, se SQL92 stesso si qualifica è aperto al dibattito. Alcune persone affermano che qualsiasi parte di codice che dice a un computer cosa fare si qualifica come linguaggio di programmazione; secondo tale definizione SQL92 è uno, ma lo è anche per esempio HTML. La definizione è piuttosto vaga, ed è una cosa inutile di cui discutere.


15

A rigor di termini, SQL è ora un linguaggio completo turing perché l'ultimo standard SQL include i "Persistent Stored Modules" (PSM). In breve, un PSM è la versione standard del linguaggio PL / SQL in Oracle (e altre estensioni procedurali simili dell'attuale DBMS).

Con l'inclusione di questi PSM, SQL è diventato completo


13

Un'istruzione select ANSI, come originariamente definita in SQL-86, non è completa perché termina sempre (tranne che per CTE ricorsivi e solo se l'implementazione supporta una ricorsione arbitrariamente profonda). Non è quindi possibile simulare nessun'altra macchina di turing. Le procedure memorizzate sono in fase di completamento ma questo è barare ;-)


1

Oracle PLSQL e Microsoft TSQL sono entrambi completati. Anche la stessa dichiarazione selezionata di Oracle è in fase di completamento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.