tdbc::postgres

Check-in [ee2ba4cd4a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Properly quote string constants and identifiers
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | medranocalvo-correct-quoting
Files: files | file ages | folders
SHA3-256:ee2ba4cd4a7478be6c9536fde8662facadf20afdb59d3d55355ac70f393b49e5
User & Date: adrianmedranocalvo 2018-09-14 17:57:30
Context
2018-09-14
18:10
Add copyright information check-in: e1181bd5af user: adrianmedranocalvo tags: medranocalvo-correct-quoting
17:57
Properly quote string constants and identifiers check-in: ee2ba4cd4a user: adrianmedranocalvo tags: medranocalvo-correct-quoting
2018-07-01
05:17
Update to latest TEA. DONT_TD_VOID was removed from unixODBC in version 2.3.1, 2011/11/28. check-in: 5cce9b482f user: stu tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tdbcpostgres.c.

396
397
398
399
400
401
402



403
404
405
406
407
408
409
....
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484


1485
1486
1487
1488


1489
1490
1491
1492

1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511

1512
1513
1514
1515
1516
1517
1518
1519

1520
1521
1522
1523
1524
1525
1526
....
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
....
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
1755







1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
....
3411
3412
3413
3414
3415
3416
3417







































3418
3419
3420
3421
3422
3423
3424
    ISOL_REPEATABLE_READ,
    ISOL_SERIALIZABLE,
    ISOL_NONE = -1
};

/* Static functions defined within this file */




static int DeterminePostgresMajorVersion(Tcl_Interp* interp,
					 ConnectionData* cdata,
					 int* versionPtr);
static void DummyNoticeProcessor(void*, const PGresult*);
static int ExecSimpleQuery(Tcl_Interp* interp, PGconn * pgPtr,
			   const char * query, PGresult** resOut);
static void TransferPostgresError(Tcl_Interp* interp, PGconn * pgPtr);
................................................................................
				/* Literal pool */
    PGresult* res,* resType;	/* Results of libpq call */
    char* columnName;		/* Name of the column */
    Oid typeOid;		/* Oid of column type */
    Tcl_Obj* retval;		/* List of table names */
    Tcl_Obj* attrs;		/* Attributes of the column */
    Tcl_Obj* name;		/* Name of a column */
    Tcl_Obj* sqlQuery = Tcl_NewStringObj("SELECT * FROM ", -1);
				/* Query used */

    Tcl_IncrRefCount(sqlQuery);

    /* Check parameters */

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "table ?pattern?");
	return TCL_ERROR;
    }



    /* Check if table exists by retreiving one row.
     * The result wille be later used to determine column types (oids) */
    Tcl_AppendObjToObj(sqlQuery, objv[2]);



    if (ExecSimpleQuery(interp, cdata->pgPtr, Tcl_GetString(sqlQuery),
			&resType) != TCL_OK) {
        Tcl_DecrRefCount(sqlQuery);

	return TCL_ERROR;
    }

    Tcl_DecrRefCount(sqlQuery);

    /* Retreive column attributes */

    sqlQuery = Tcl_NewStringObj("SELECT "
	"  column_name,"
	"  numeric_precision,"
	"  character_maximum_length,"
	"  numeric_scale,"
	"  is_nullable"
	"  FROM information_schema.columns"
	"  WHERE table_name='", -1);
    Tcl_IncrRefCount(sqlQuery);
    Tcl_AppendObjToObj(sqlQuery, objv[2]);

    if (objc == 4) {

	Tcl_AppendToObj(sqlQuery,"' AND column_name LIKE '", -1);
	Tcl_AppendObjToObj(sqlQuery, objv[3]);
    }
    Tcl_AppendToObj(sqlQuery,"'", -1);

    if (ExecSimpleQuery(interp, cdata->pgPtr,
			Tcl_GetString(sqlQuery), &res) != TCL_OK) {
        Tcl_DecrRefCount(sqlQuery);

	PQclear(resType);
	return TCL_ERROR;
    } else {
	int i, j;
	retval = Tcl_NewObj();
	Tcl_IncrRefCount(retval);
	for (i = 0; i < PQntuples(res); i += 1) {
................................................................................

	    Tcl_DictObjPut(NULL, attrs, literals[LIT_NULLABLE],
		    Tcl_NewIntObj(strcmp("YES",
			    PQgetvalue(res, i, 4)) == 0));
	    Tcl_DictObjPut(NULL, retval, name, attrs);
	}

	Tcl_DecrRefCount(sqlQuery);
	Tcl_SetObjResult(interp, retval);
	Tcl_DecrRefCount(retval);
	PQclear(resType);
	PQclear(res);
	return TCL_OK;
    }
}
................................................................................
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    Tcl_Obj** literals = cdata->pidata->literals;
				/* Literal pool */
    PGresult* res;		/* Result of libpq call */
    char * field;		/* Field value from SQL result */
    Tcl_Obj* retval;		/* List of table names */
    Tcl_Obj* sqlQuery = Tcl_NewStringObj("SELECT tablename"
					 " FROM pg_tables"
					 " WHERE  schemaname = 'public'",
					 -1);
				/* SQL query for table list */
    int i;
    Tcl_IncrRefCount(sqlQuery);


    /* Check parameters */

    if (objc < 2 || objc > 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }








    if (objc == 3) {

	/* Pattern string is given */

	Tcl_AppendToObj(sqlQuery, " AND  tablename LIKE '", -1);
	Tcl_AppendObjToObj(sqlQuery, objv[2]);
	Tcl_AppendToObj(sqlQuery, "'", -1);
    }

    /* Retrieve the table list */

    if (ExecSimpleQuery(interp, cdata ->pgPtr, Tcl_GetString(sqlQuery),
			&res) != TCL_OK) {
	Tcl_DecrRefCount(sqlQuery);
	return TCL_ERROR;
    }
    Tcl_DecrRefCount(sqlQuery);

    /* Iterate through the tuples and make the Tcl result */

    retval = Tcl_NewObj();
    for (i = 0; i < PQntuples(res); i+=1) {
	if (!PQgetisnull(res, i, 0)) {
	    field = PQgetvalue(res, i, 0);
................................................................................
   if (--pgRefCount == 0) {
       Tcl_FSUnloadFile(NULL, pgLoadHandle);
       pgLoadHandle = NULL;
   }
   Tcl_MutexUnlock(&pgMutex);

}








































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * End:
 */







>
>
>







 







|
<
<
<







>
>



|
>
>

|

<
>



|



|






|
|
<


>
|
<

<


|
<
>







 







|







 







<
<
<
<
<

<
>








>
>
>
>
>
>
>




|
|
<




|

|


|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
....
1470
1471
1472
1473
1474
1475
1476
1477



1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495

1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516

1517

1518
1519
1520

1521
1522
1523
1524
1525
1526
1527
1528
....
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
....
1736
1737
1738
1739
1740
1741
1742





1743

1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765

1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
....
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
    ISOL_REPEATABLE_READ,
    ISOL_SERIALIZABLE,
    ISOL_NONE = -1
};

/* Static functions defined within this file */

static void AppendSQLStringConstant(Tcl_DString *dsPtr, Tcl_Obj *stringObj);
static void AppendSQLIdentifier(Tcl_DString *dsPtr, Tcl_Obj *stringObj);

static int DeterminePostgresMajorVersion(Tcl_Interp* interp,
					 ConnectionData* cdata,
					 int* versionPtr);
static void DummyNoticeProcessor(void*, const PGresult*);
static int ExecSimpleQuery(Tcl_Interp* interp, PGconn * pgPtr,
			   const char * query, PGresult** resOut);
static void TransferPostgresError(Tcl_Interp* interp, PGconn * pgPtr);
................................................................................
				/* Literal pool */
    PGresult* res,* resType;	/* Results of libpq call */
    char* columnName;		/* Name of the column */
    Oid typeOid;		/* Oid of column type */
    Tcl_Obj* retval;		/* List of table names */
    Tcl_Obj* attrs;		/* Attributes of the column */
    Tcl_Obj* name;		/* Name of a column */
    Tcl_DString ds, *dsPtr = &ds;




    /* Check parameters */

    if (objc < 3 || objc > 4) {
	Tcl_WrongNumArgs(interp, 2, objv, "table ?pattern?");
	return TCL_ERROR;
    }

    Tcl_DStringInit(dsPtr);

    /* Check if table exists by retreiving one row.
     * The result wille be later used to determine column types (oids) */
    Tcl_DStringAppend(dsPtr, "SELECT * FROM ", -1);
    AppendSQLIdentifier(dsPtr, objv[2]);
    Tcl_DStringAppend(dsPtr, " LIMIT 0", -1);

    if (ExecSimpleQuery(interp, cdata->pgPtr, Tcl_DStringValue(dsPtr),
			&resType) != TCL_OK) {

	Tcl_DStringFree(dsPtr);
	return TCL_ERROR;
    }

    Tcl_DStringSetLength(dsPtr, 0);

    /* Retreive column attributes */

    Tcl_DStringAppend(dsPtr, "SELECT "
	"  column_name,"
	"  numeric_precision,"
	"  character_maximum_length,"
	"  numeric_scale,"
	"  is_nullable"
	"  FROM information_schema.columns"
	"  WHERE table_name=", -1);
    AppendSQLStringConstant(dsPtr, objv[2]);


    if (objc == 4) {
	Tcl_DStringAppend(dsPtr, " AND column_name LIKE ", -1);
	AppendSQLStringConstant(dsPtr, objv[3]);

    }


    if (ExecSimpleQuery(interp, cdata->pgPtr,
			Tcl_DStringValue(dsPtr), &res) != TCL_OK) {

	Tcl_DStringFree(dsPtr);
	PQclear(resType);
	return TCL_ERROR;
    } else {
	int i, j;
	retval = Tcl_NewObj();
	Tcl_IncrRefCount(retval);
	for (i = 0; i < PQntuples(res); i += 1) {
................................................................................

	    Tcl_DictObjPut(NULL, attrs, literals[LIT_NULLABLE],
		    Tcl_NewIntObj(strcmp("YES",
			    PQgetvalue(res, i, 4)) == 0));
	    Tcl_DictObjPut(NULL, retval, name, attrs);
	}

	Tcl_DStringFree(dsPtr);
	Tcl_SetObjResult(interp, retval);
	Tcl_DecrRefCount(retval);
	PQclear(resType);
	PQclear(res);
	return TCL_OK;
    }
}
................................................................................
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    Tcl_Obj** literals = cdata->pidata->literals;
				/* Literal pool */
    PGresult* res;		/* Result of libpq call */
    char * field;		/* Field value from SQL result */
    Tcl_Obj* retval;		/* List of table names */





    int i;

    Tcl_DString ds, *dsPtr = &ds;

    /* Check parameters */

    if (objc < 2 || objc > 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    Tcl_DStringInit(dsPtr);
    Tcl_DStringAppend(dsPtr,
		      "SELECT tablename"
		      " FROM pg_tables"
		      " WHERE  schemaname = 'public'",
		      -1); /* SQL query for table list */

    if (objc == 3) {

	/* Pattern string is given */

	Tcl_DStringAppend(dsPtr, " AND  tablename LIKE ", -1);
	AppendSQLStringConstant(dsPtr, objv[2]);

    }

    /* Retrieve the table list */

    if (ExecSimpleQuery(interp, cdata ->pgPtr, Tcl_DStringValue(dsPtr),
			&res) != TCL_OK) {
	Tcl_DStringFree(dsPtr);
	return TCL_ERROR;
    }
    Tcl_DStringFree(dsPtr);

    /* Iterate through the tuples and make the Tcl result */

    retval = Tcl_NewObj();
    for (i = 0; i < PQntuples(res); i+=1) {
	if (!PQgetisnull(res, i, 0)) {
	    field = PQgetvalue(res, i, 0);
................................................................................
   if (--pgRefCount == 0) {
       Tcl_FSUnloadFile(NULL, pgLoadHandle);
       pgLoadHandle = NULL;
   }
   Tcl_MutexUnlock(&pgMutex);

}

/*
 *-----------------------------------------------------------------------------
 *
 * AppendSQLDelimited --
 *
 *	Convert a string into a safe delimited string and append it to the
 *	dynamic string.
 *
 *-----------------------------------------------------------------------------
 */
static void
AppendSQLDelimited(Tcl_DString *dsPtr, Tcl_Obj *stringObj, char delimiter) {
    int b, e;
    int len = 0;
    char *str = Tcl_GetStringFromObj(stringObj, &len);
    Tcl_DStringAppend(dsPtr, &delimiter, 1);
    for (b = 0, e = 0; e < len; e++) {
	if (str[e] == delimiter) {
	    Tcl_DStringAppend(dsPtr, &str[b], e - b);
	    Tcl_DStringAppend(dsPtr, &delimiter, 1);
	    Tcl_DStringAppend(dsPtr, &delimiter, 1);
	    b = e+1;
	}
    }
    Tcl_DStringAppend(dsPtr, &str[b], e - b);
    Tcl_DStringAppend(dsPtr, &delimiter, 1);
}

static void
AppendSQLStringConstant(Tcl_DString *dsPtr, Tcl_Obj *stringObj) {
    AppendSQLDelimited(dsPtr, stringObj, '\'');
}

static void
AppendSQLIdentifier(Tcl_DString *dsPtr, Tcl_Obj *stringObj) {
    AppendSQLDelimited(dsPtr, stringObj, '"');
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * End:
 */