SofiaDB · referencia de SQL#

Consejo

En corto: SofiaDB entiende un subconjunto del SQL de PostgreSQL, escrito a mano y sin NULL: CREATE/DROP/ALTER, INSERT, SELECT con JOIN, subconsultas y agregados, UPDATE, DELETE, transacciones y EXPLAIN. Una sentencia por llamada. Lo que no entiende lo rechaza con un mensaje que dice qué usar en su lugar; esta página los lista con su texto exacto.

Cada ejemplo de esta página se ejecuta en las pruebas del motor, y cada rechazo se comprueba con su mensaje. Para usar el SQL desde una app, mira SofiaDB desde el lenguaje; para el motor, SofiaDB.

Reglas generales#

Léxico#

ElementoRegla
Comentarios-- hasta el fin de línea y /* en bloque */. Sin cerrar: «comentario /* sin cerrar»
Texto'entre comillas simples'; una comilla dentro se escribe doble: 'it''s'. Sin cerrar: «texto sin cerrar en la posición N»
IdentificadoresLetras (también Unicode), dígitos y _. Sin comillas se pasan a minúsculas; "entre comillas dobles" se respetan tal cual. Sin cerrar: «identificador " sin cerrar»; vacío: «identificador vacío ""»
NúmerosEntero de 64 bits; con punto, o demasiado grande, es decimal. Pegado a una letra: «número mal escrito en la posición N»
Parámetros$1, $2…; otra forma: «parámetro inválido en la posición N: se escribe $1, $2…»
Símbolos<> != <= >= || :: ( ) , ; * + - / % = < > y .
Otro carácter«carácter inesperado «c» en la posición N»
TamañoHasta 1 MiB de SQL: «el SQL ocupa más de 1024 KiB»

Palabras reservadas (no sirven de nombre sin comillas): select from where group order by having limit offset and or not as asc desc in like between is null true false values set insert update delete create drop table into primary key default distinct case when then else end join on union all inner left right full outer cross natural using exists.

Nombres de tablas, columnas e índices: de 1 a 63 bytes, sin caracteres de control («nombre inválido: «n» (1 a 63 bytes, sin caracteres de control)»).

Tipos#

TipoNombres aceptadosNotas
Entero (64 bits)integer, int, int4, int8, bigint, smallint, int2, entero
Textotext, texto, varchar, char, character (con varying y (n) opcionales)El tamaño (n) se ignora
Lógicoboolean, bool, logico, lógicotrue y false
Bytesbytea, bytes
Decimal exactonumeric, decimal, con (p) o (p,s)p de 1 a 38 y s de 0 a p: «DECIMAL(p,s): la precisión va de 1 a 38 y la escala de 0 a la precisión»
Instantetimestamptz, timestamp, instanteMilisegundos desde 1970

Otro nombre: «tipo desconocido: x».

CREATE TABLE#

CREATE TABLE [IF NOT EXISTS] t (
  columna tipo [restricciones de columna],
  …,
  [restricciones de tabla]
)

Restricciones de columna, en cualquier orden: PRIMARY KEY [AUTOINCREMENT], UNIQUE, NOT NULL, DEFAULT expr, CHECK (expr), REFERENCES t [(col)] y CONSTRAINT nombre delante de cualquiera.

Restricciones de tabla (con CONSTRAINT nombre opcional): UNIQUE (cols), CHECK (expr), FOREIGN KEY (cols) REFERENCES t [(cols)] [ON DELETE|UPDATE RESTRICT|NO ACTION] y PRIMARY KEY (col).

CREATE TABLE cita (
  id INTEGER PRIMARY KEY,
  profesional TEXT NOT NULL,
  inicio TIMESTAMPTZ DEFAULT 0,
  monto NUMERIC(10,2) DEFAULT 0,
  CHECK (monto >= 0)
)

CREATE INDEX y DROP#

CREATE [UNIQUE] INDEX [IF NOT EXISTS] nombre ON t (col [ASC], …) [WHERE predicado]
DROP TABLE [IF EXISTS] t
DROP INDEX [IF EXISTS] nombre
CREATE UNIQUE INDEX cita_hora ON cita (profesional, inicio)
CREATE INDEX cita_cara ON cita (inicio) WHERE monto > 100

ALTER TABLE#

ALTER TABLE t ADD [COLUMN] columna tipo [DEFAULT expr] [NOT NULL]

Es la única forma de cambiar columnas: «de ALTER TABLE solo hay ADD COLUMN, POLITICA INQUILINO col, SIN POLITICA, AUDITAR y SIN AUDITAR». Las filas que ya existen necesitan un valor, así que DEFAULT es obligatorio: «añadir la columna X necesita DEFAULT: las filas que ya existen deben tener un valor (SofiaDB no usa NULL)».

Tampoco se puede añadir:

IntentoMensaje
Una clave primaria«no se puede añadir una clave primaria a una tabla que ya existe»
UNIQUE o CHECK«ADD COLUMN no admite UNIQUE ni CHECK: añade la columna y crea después CREATE UNIQUE INDEX»
REFERENCES«ADD COLUMN no admite REFERENCES: declara la clave foránea al crear la tabla»
Pasar de 1000 columnas«una tabla tiene como mucho 1000 columnas»
Una columna que ya existe«la columna X ya existe»

INSERT#

INSERT [OR REPLACE | OR IGNORE] INTO t [(col, …)] VALUES (v, …), (v, …)
REPLACE INTO t [(col, …)] VALUES (v, …)
INSERT INTO cita (id, profesional, inicio) VALUES (1, 'ana', 1790586000000), (2, 'luis', 1790589600000)
INSERT OR IGNORE INTO cita (id, profesional) VALUES (1, 'otra')
INSERT OR REPLACE INTO cita (id, profesional) VALUES (1, 'otra')

SELECT#

SELECT { * | alias.* | expr [[AS] alias] }, …
  [FROM fuente [JOIN …]]
  [WHERE predicado]
  [GROUP BY expr, …] [HAVING predicado]
  [ORDER BY expr [ASC|DESC], …]
  [LIMIT expr] [OFFSET expr]

LIMIT y OFFSET pueden ir en cualquier orden. Un SELECT sin FROM vale (SELECT 1 + 1). Una columna sin alias se llama como la columna, o count, sum, min, max si es un agregado.

SELECT DISTINCT se rechaza: «SELECT DISTINCT no está soportado».

FROM y JOIN#

La fuente es t [[AS] alias] o una tabla derivada (SELECT …) [AS] alias (el alias es obligatorio). Un FROM junta hasta 16 fuentes.

SELECT c.id, c.profesional, p.nombre
FROM cita c
INNER JOIN profesional p ON p.id = c.profesional_id
LEFT JOIN sala s ON s.id = c.sala_id

Subconsultas#

FormaEjemplo
EscalarSELECT (SELECT max(id) FROM cita)
IN / NOT INWHERE id IN (SELECT cita_id FROM pago)
EXISTS / NOT EXISTSWHERE EXISTS (SELECT id FROM pago WHERE pago.cita_id = cita.id)
Tabla derivadaFROM (SELECT profesional FROM cita) t

Una subconsulta puede referirse a columnas de la consulta que la contiene (correlada), con hasta 24 niveles. Una escalar sin filas da el valor vacío del tipo.

Agregados y agrupación#

count(*), count(e), sum(e), min(e) y max(e), con GROUP BY y HAVING.

SELECT profesional, count(*), sum(id) FROM cita GROUP BY profesional HAVING count(*) > 1 ORDER BY profesional

Expresiones#

De menor a mayor precedencia:

NivelOperadores
1OR
2AND
3NOT
4= <> != < <= > >=, BETWEEN, IN (lista), LIKE, y sus NOT
5|| (concatenar texto)
6+ -
7* / %
8+ y - unarios
9Literales, columnas, $n, paréntesis, funciones, subconsultas

Funciones#

FunciónQué hace
lower(t), upper(t)Minúsculas y mayúsculas
length(x), char_length(x)Caracteres de un texto, o bytes de un BYTES
abs(n)Valor absoluto de un entero o decimal
trim(t)Quita los espacios de los extremos (solo espacios)
substr(t, desde [, largo]), substring(…)Posiciones desde 1
encode(bytes, 'base64'|'hex')BYTES a texto
decode(texto, 'base64'|'hex')Texto a BYTES
SELECT upper(profesional), length(profesional), substr(profesional, 1, 2) FROM cita

UPDATE y DELETE#

UPDATE t SET col = expr, … [WHERE predicado]
DELETE FROM t [WHERE predicado]
UPDATE cita SET monto = monto + 1 WHERE id = 2
DELETE FROM cita WHERE inicio < 1790000000000

Ambas devuelven las filas afectadas. Sin WHERE actúan sobre toda la tabla. Una columna asignada dos veces: «la columna c se asigna dos veces». Las restricciones (UNIQUE, CHECK, claves foráneas) se comprueban al final de la sentencia; si fallan, la sentencia no deja nada.

Transacciones#

BEGIN [TRANSACTION | WORK]
START TRANSACTION
COMMIT | END [TRANSACTION | WORK]
ROLLBACK [TRANSACTION | WORK]

Sin BEGIN, cada sentencia es su propia transacción. Lo confirmado sobrevive a un corte de luz. Si otra transacción confirmó antes un cambio en lo que esta leyó, falla con CONFLICTO_SERIALIZACION y hay que repetirla (una sentencia suelta se repite sola). Una transacción acepta hasta 64 MiB de cambios y dura a lo más 30 s; pasado eso falla: «la transacción lleva abierta más de 30 s: confírmala o divídela en partes más cortas».

EXPLAIN#

EXPLAIN SELECT * FROM cita WHERE profesional = 'ana'

Devuelve en texto el plan (qué índice usa, cómo junta). Solo vale para SELECT, UPDATE y DELETE: «EXPLAIN solo vale para SELECT, UPDATE y DELETE».

Códigos de error estables#

Los errores de restricción y de concurrencia empiezan por un código que un programa puede comparar:

CódigoCuándo
UNICO_VIOLADO:<índice>Clave primaria o UNIQUE repetido
FORANEA_VIOLADA:<restricción>Fila hija sin madre, o madre con hijas
COMPROBAR_VIOLADO:<restricción>Un CHECK no se cumple
CONFLICTO_SERIALIZACIONOtra transacción cambió antes lo leído
SOLO_LECTURACambio en una sesión de solo lectura
TIEMPO_AGOTADO, CANCELADAConsulta que pasó su tiempo o fue cancelada
CLAVE_REQUERIDA, CLAVE_INVALIDABase cifrada sin clave, o con clave que no la abre

Límites#

QuéLímite
Sentencias por llamada1
Tamaño del SQL1 MiB
Parámetros por sentencia65 535
Columnas por tabla1000
Fuentes en un FROM16
Niveles de subconsultas24
Anidación de una expresión128 niveles
Operandos encadenados256
Una fila16 MiB
Una clave1 KiB
Memoria al juntar o agrupar64 MiB
Cambios de una transacción64 MiB
Duración de una transacción30 s